SpringMVC与Freemarker的集成以及多视图解析器配置

2023-11-15

一、Spring MVC视图解析器

视图解析器的工作流程大致是这样的:Controller的某个方法执行完成以后,返回一个视图(比如:listUser),视图解析器要做的工作就是找到某个对象

来完成视图的渲染,或者跳转到其他的逻辑视图。这里的渲染对象通常就是我们的jsp文件或者我们下面用的Freemarker(例如listUser.jsp或者

listUser.ftl)。渲染完成以后,将解析结果发送到客户端浏览器。

下面介绍一下本文需要用到的解析器(更多解析器资料,请参考 http://e-freya.iteye.com/blog/384083 ):

InternalResourceViewResolver:这是一个最常用的解析器。通常使用它指定渲染对象为jsp页面。

FreeMarkerViewResolver:这就是Spring与Freemarker整合需要用到的解析器。

二、详细配置:

1.Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>SpringmvcFreemarker</display-name>
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

2.applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd"
            >
     <!--通用视图解析器-->  
    <bean id="viewResolverCommon" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/page/"/>    
        <property name="suffix" value=".jsp"/> <!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑  -->  
        <property name="viewClass">  
            <value>org.springframework.web.servlet.view.InternalResourceView</value>  
        </property>  
        <property name="order" value="1"/>  
    </bean>  
    <!-- 配置freeMarker视图解析器 -->  
    <bean id="viewResolverFtl" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>  
        <property name="contentType" value="text/html; charset=utf-8"/>  
        <property name="cache" value="true" />  
        <property name="suffix" value=".ftl" />
        <property name="order" value="0"/>  
    </bean>  
    <!-- 配置freeMarker的模板路径 -->  
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
        <property name="templateLoaderPath">  
            <value>/WEB-INF/ftl/</value>  
        </property>  
        <property name="freemarkerVariables">  
            <map>  
                <entry key="xml_escape" value-ref="fmXmlEscape" />  
            </map>  
        </property>  
        <property name="defaultEncoding">  
            <value>utf-8</value>  
        </property>  
        <property name="freemarkerSettings">  
            <props>  
                <prop key="template_update_delay">3600</prop>  
            </props>  
        </property>  
    </bean>  
    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>  
    <!-- 注解支持 -->    
    <mvc:annotation-driven/>  
    <!-- 对包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 -->  
    <context:component-scan base-package="dhp.springmvc.freemarker">  
        <!-- 允许定义过滤器将基包下的某些类纳入或排除  
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> -->  
    </context:component-scan>  
</beans>


3.UserController

package dhp.springmvc.freemarker;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/freeMarker")
public class UserController {
	@RequestMapping("/hello")
    public String sayHello(ModelMap map) {
        System.out.println("say Hello ……");
        map.addAttribute("name", " World!");
        return "/hello";
    }
    @RequestMapping("/hi")
    public String sayHi(ModelMap map) {
        System.out.println("say hi ……");
        map.put("name", "jojo");
        return "/hi";
    }
    @RequestMapping("/jsp")
    public String jspRequest(ModelMap map) {
        System.out.println("jspRequest ……");
        map.put("name", "jsp");
        return "/temp";
    }
}

在视图解析器中有一个<property name="order" value="orderValue"/>的配置,这个配置表示解析器的优先级别。我们将FreeMarkerViewResolver的级别设为0,将InternalResourceViewResolver的级别设为1。这样,解析器就会优先使用 FreeMarkerViewResolver 进行解析,如果找不到相应的模板,就使用InternalResourceViewResolver进行解析,如果还找不到页面,就会产生一个404错误!

在本例中,我们在/WEB-INF/page/下有一个temp.jsp页面,在/WEB-INF/ftl/下有一个hello.ftl和hi.ftl的模板文件。那么当访问freeMarker/hello的时候或者 freeMarker/hi,Controller返回一个视图对象,根据解析器配置,先使用FreeMarkerViewResolver进行解析。它会根据模板路径templateLoaderPath的配置/WEB-INF/ftl/下去找是否有一个hello和hi并且以后缀配置suffix值.ftl,即 hello.ftl和hi.ftl文件,如果找到则使用该模板进行解析。


当用户访问freeMarker/jsp的时候,返回temp视图,毅然先使用FreeMarkerViewResolver进行解析,结果发现在/WEB-INF/ftl/下并没有temp.ftl这个模板文件,于是使用InternalResourceViewResolver进行解析,于是开始寻找/WEB-INF/page/下是否有showUser.jsp文件。由于我们已经创建了这个文件,于是最终使用temp.jsp进行渲染。那么如果没有找到temp.jsp,就会抛出404错误。

这里还要注意的是,如果Controller中返回视图加了后缀jsp或者ftl,在配置中就不要加入suffix配置,否则会找不到页面。


附:

freemarker常见语法

FreeMarker的插值有如下两种类型:1,通用插值${expr};2,数字格式化插值:#{expr}或#{expr;format}

${book.name?if_exists } //用于判断如果存在,就输出这个值

${book.name?default(‘xxx’)}//默认值xxx
${book.name!"xxx"}//默认值xxx
${book.date?string('yyyy-MM-dd')} //日期格式
${book?string.number} 20 //三种不同的数字格式
${book?string.currency}--<#-- $20.00 -->
${book?string.percent}—<#-- 20% -->


<#assign foo=ture /> //声明变量,插入布尔值进行显示
${foo?string("yes","no")} <#-- yes -->


大小比较符号使用需要注意:(xml的原因),可以用于比较数字和日期
使用lt、lte、gt和gte来替代<、<=、>和>= 也可以使用括号<#if (x>y)>


内置函数: 调用区别于属性的访问,使用?代替.
常见的一些内置函数
对于字符串
html-对字符串进行HTML编码
cap_first-使字符串第一个字母大写
lower_case-将字符串转换成小写
trim-去掉字符串前后的空白字符


示例:${“freeMarker”?cap_first}





对于Sequences(序列)
size-获得序列中元素的数目


对于数字
int-取得数字的整数部分(如-1.9?int的结果是-1)


对于集合,可以使用数组的方式,使用下标索引进行访问


逻辑判断:
if................


<#if condition>...
<#elseif condition2>...
<#elseif condition3>......
<#else>...
Boolean类型的空值判断
空值判断可以写成<#if book.name?? > //注意${}为变量的渲染显示,而<>为定义等操作符的定义


switch............
<#switch value>
<#case refValue1>
...
<#break>
<#case refValue2>
...
<#break>
...
<#case refValueN>
...
<#break>
<#default>
...
</#switch>


快速定义int区间的集合
<#assign l=0..100/> //注意不需要[]


3:循环读取集合: 注意/的使用
<#list student as stu>
${stu}<br/>
</#list>
与jstl循环类似,也可以访问循环的状态
item_index:当前变量的索引值
item_has_next:是否存在下一个对象 其中item名称为as后的变量名,如stu


集合长度判断
<#if student?size != 0></#if> 判断=的时候,注意只要一个=符号,而不是==


宏/模板
初步了解: 使用更像一个闭包closure,可以定义后,在脚本中任意地方引用,并原地起作用
<#macro greet>
<font size="+2">Hello Joe!</font>
</#macro>
使用的方式为:
<@greet></@greet> //同xml可以简写成<@greet/>


宏的参数定义,类似js,在宏名后 带参数进行传递定义
<#macro greet person color>
${person}
</#macro>


调用带参数时,注意使用类似XML的属性格式进行传递,不需要关心顺序问题
<@greet person="Fred" color="black"/>


参数默认值定义,如果没有,就必须要求传递完整的参数列表
<#macro greet person color="black">
<font size="+2" color="${color}">Hello ${person}!</font>
</#macro>


使用xml的嵌套内容进行传递宏调用,关键标签 <#nested>
<#macro border>
<table border=4 cellspacing=0 cellpadding=4><tr><td>
<#nested>
</tr></td></table>
</#macro>


调用时:
<@border>The bordered text</@border>


<#nested> 标签可以在宏中多次调用,也可以将多个宏组合进行嵌套


for循环的精简版:
<#list 1..count as x>
</#list>


宏的循环变量,配合嵌套标签进行参数传递,
<#macro repeat count>
<#list 1..count as x>
<#nested x, x/2, x==count> //这里的三个参数,将会传递到嵌套内容中
</#list>
</#macro>


<@repeat count=4 ; c, halfc, last>
${c}. ${halfc}<#if last> Last!</#if> //这里的内容由macro中的<#nested>进行参数的传递,传递的数量任意,当注意需要宏接受这些
</@repeat>
上述还需要注意;的使用


参数的数量是可变的,并不要求全部都有,但是效果不同


在模板中定义变量
在模板中定义的变量有三种类型:
plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换。
局部变量:在宏定义体中有效,使用local指令创建和替换。
循环变量:只能存在于指令的嵌套内容,由指令(如list)自动创建;宏的参数是局部变量,而不是循环变量


<#assign x = "plain"> //全局的plain变量
内部循环变量将会隐藏同名的外部循环变量


外部导入的使用,可以用于模块化,并且提供公用性
如:lib/my_lib.ftl文件
<#macro copyright date>
<p>Copyright (C) ${date} Julia Smith. All rights reserved.
<br>Email: ${mail}</p>
</#macro>
<#assign mail = "jsmith@acme.com">


lib/my_inc.ftl文件
<#import "/lib/my_test.ftl" as my>
<#assign mail="fred@acme.com">
<@my.copyright date="1999-2002"/>
${my.mail}
${mail}
输出结果将不会出现冲突


对于库中的变量修改,使用in关键字
<#assign mail="jsmith@other.com" in my>


函数定义:区别于宏对象,带返回值
<#function name param1 param2><#return val></#function>函数,有返回参数


stringA[M .. N] 取子字符串,类似substring(stringA, M, N)


<#include "/copyright_footer.html"> 导入其他页面元素
<#include filename options>
options包含两个属性
encoding=”GBK” 编码格式
parse=true 是否作为ftl语法解析,默认是true,false就是以文本方式引入.注意在ftl文件里布尔值都是直接赋值的如parse=true,而不是


parse=”true”


hash与list的定义
<#assign c= {"a":"orz","b":"czs"}>
${c.a}


List片段可以采用: products[10..19] or products[5..] 的格式进行定义,当只局限于数字
<#assign c= [1,2,3,4,5,6,6,7]>
<#list c[1..3] as v>
${v}
</#list>


对变量的缺省处理
product.color!"red"


用compress directive或者transform来处理输出。
<#compress>...</#compress>:消除空白行。
<@compress single_line=true>...</@compress>将输出压缩为一行。都需要包裹所需文档


freemarker可用"["代替"<".在模板的文件开头加上[#ftl].


注释部分
<#-- 注释部分 -->


数字输出的另外一种方式
#{c.a;m0} 区别于${},这个例子是用于输出数字的格式化,保留小数的位数,详细如下


数字格式化插值可采用#{expr;format}形式来格式化数字,其中format可以是:
mX:小数部分最小X位
MX:小数部分最大X位


在定义字符串的时候,可以使用''或者"",对特殊字符,需要使用\进行转义


如果存在大量特殊字符,可以使用${r"..."}进行过滤
${r"${foo}"}
${r"C:\foo\bar"}


Map对象的key和value都是表达式,但是key必须是字符串
可以混合使用.和[""]访问
book.author["name"] //混合使用点语法和方括号语法


为了处理缺失变量,FreeMarker提供了两个运算符: 用于防止对象不存在而导致的异常
!:指定缺失变量的默认值
??:判断某个变量是否存在,返回boolean值


noparse指令指定FreeMarker不处理该指定里包含的内容,该指令的语法格式如下:
<#noparse>...</#noparse>


${firstName?html} 使用html对字符进行格式化处理,对于<等的过滤


escape , noescape指令,对body内的内容实用统一的表达式
看如下的代码:
<#escape x as x?html>
First name:${firstName}
Last name:${lastName}
Maiden name:${maidenName}
</#escape>
上面的代码等同于:
First name:${firstName?html}
Last name:${lastName?html}
Maiden name:${maidenName?html}


定义全局变量的方式
<#assign name1=value1 name2=value2 / > // 可以同时定义多个变量,也可以使用循环来给变量赋值
<#assign x>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
${n}
</#list>
</#assign>
${x}


setting指令,用于动态设置freeMarker的运行环境:


该指令用于设置FreeMarker的运行环境,该指令的语法格式如下:<#setting name=value>,在这个格式中,name的取值范围包含如下几个:
locale:该选项指定该模板所用的国家/语言选项
number_format:指定格式化输出数字的格式
boolean_format:指定两个布尔值的语法格式,默认值是true,false
date_format,time_format,datetime_format:指定格式化输出日期的格式
time_zone:设置格式化输出日期时所使用的时区


<#return> 用于退出宏的运行


?html 用于将字符串中可能包含的html字符,进行过滤.


调用Java方法,需要使用实现TemplateMethodModel接口,但是好像会覆盖掉属性的访问



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMVC与Freemarker的集成以及多视图解析器配置 的相关文章

随机推荐

  • “华为杯”研究生数学建模竞赛2004年-【华为杯】D题:研究生录取问题的双向选择策略(附一等奖获奖论文)

    赛题描述 根据素质教育和培养高素质合格人才的要求 目前各学校都对硕士研究生的录取方法进行改革 即在录取的过程中改变了以往根据考试成绩定终身的做法 加大了复试的作用 一般是根据初试的成绩 在达到国家和学校分数线的学生中从高分到低分排序 按1
  • 读《洞穴奇案》——从虐猫到禁食狗肉,自然法真的存在吗?

    这是读 洞穴奇案 的第四篇心得体会 本篇的题目一下子就包含了两个热点话题 高校学生虐猫案 和 立法禁止吃狗肉 这两个事件不得不说是争议不断的 从理性和感性的角度出发得出的结论不一而足 如果此人像探险者一样并没有邪恶的意图 而我们判他有罪 判
  • 什么是U-Boot以及如何下载U-Boot源码

    参考 什么是U Boot以及如何下载U Boot源码 作者 一只青木呀 发布时间 2020 10 20 11 05 59 网址 https blog csdn net weixin 45309916 article details 1091
  • 谷歌地图api訪问失败

    在非外网情况下 我们调用谷歌api会出现载入不到地图的现象 此时能够换一下域名试试或许就好了 比方我自己訪问api时时这样写的 https maps googleapis com maps api js key sensor true 此时
  • Java中Iterator和Iterable的区别

    iterator为Java中的迭代器对象 是能够对List这样的集合进行迭代遍历的底层依赖 iterable接口里定义了返回iterator的方法 相当于对iterator的封装 同时实现了iterable接口的类可以支持forEach循环
  • 多合一网络分析平台Matomo

    什么是 Matomo Matomo 以前称为 Piwik 是领先的开源分析平台 可以让您轻松地从访问者那里获得您想要的信息 例如查看您的网站访问者来自何处 正在查看哪些页面 单击了哪些链接以及其他各种有用的信息 写 Umami 时 网友 J
  • 困惑:单元测试该在什么时候写?

    原文 http www codinghorror com blog 2005 04 good test bad test html 作者 Jeff Atwood 很多年以来 用于随机测试 ad hoc test 的工具我都是自己开发的 但在
  • 【深度学习】基础网络 (Basemodel) 综述

    以下是我在2018年7月份找工作时 根据个人所学总结出的基础网络 Basemodel 综述 其中 仅仅挑出我认为比较重要的一系列基础网络 按照时间顺序进行简要概述 如有阐述不对的地方 恳请指出 LeNet 时间 1998 意义 标志着 CN
  • 关于用pytorch构建vgg网络实现花卉分类的学习笔记

    需要的第三方库 pytorch matplotlib json os tqdm 一 model py的编写 1 准备工作 1 参照vgg网络结构图 如下图1 定义一个字典 用于存放各种vgg网络 字典如下图2 M表示最大池化层 2 定义一个
  • Android 正则表达式- 只保留字母数字

    正则表达式是对字符串操作的一种逻辑公式 就是用事先定义好的一些特定字符 及这些特定字符的组合 组成一个 规则字符串 这个 规则字符串 用来表达对字符串的一种过滤逻辑 1 匹配字母 大写 小写 和数字的字符 正则表达式 a zA Z0 9 2
  • 幂级数和函数经典例题_幂级数和函数的几种常见解法

    幂级数和函数的几种常见解法 方 艳 1 程 航 2 摘 要 摘要 无穷级数是微积分学的重要组成部分 在数学理论研究和工程 实际应用上起着举足轻重的作用 有关无穷级数里最常见的一类函数项级数 幂级数问题的研究在大学数学教学中显得十分有意义 该
  • 毕业设计 - 基于Java web的旅游系统设计【源码+论文】

    文章目录 前言 一 项目设计 1 模块设计 2 实现效果 二 部分源码 项目源码 前言 今天学长向大家分享一个 Java web 毕业设计设计项目 基于Java web的旅游网站设计 一 项目设计 1 模块设计 该系统功能设计相对比较全面
  • HTTP的升级之路

    HTTP的升级之路 HTTP简介 HTTP HyperText Transfer Protocol 超文本传输协议 是一种用于分布式 协作式和超媒体信息系统的应用层协议 1 HTTP是万维网的数据通信的基础设计HTTP最初的目的是为了提供一
  • XCode5添加新VIEW编译找不到及控件不显示的设置

    在ios6中添加没有这个问题 在ios7中添加view居然不显示 经研究办法如下 view继承自UIViewController并生成xib 主要在Build Phases中设置 1 在Complie Sources处点击加号 选择view
  • 华为OD题目: 关联端口组合并

    package com sf ccmas video config odd od11 import java util 关联端口组合并 时间限制 1s空间限制 256MB 限定语言 不限 题目描述 有M 1 lt M lt 10 个端口组
  • C#chart控件绘制折线图、柱状图、饼图、雷达图

    转载来源 https blog csdn net u011854789 article details 82946553 参考链接 http www cnblogs com winshe articles 6604406 html http
  • Python-----有关判断语句练习题以及题目解析(1)

    Python判断语句练习题及解析 1 你可以通过询问5个问题来找出你朋友的生日在 一个月中的哪天 每个问题都在询问这一天是否在5个数字集中 生日就是出现这个数字的集合的第 L 个数字的和 例如 如果生日是19 那它就会在setl set2和
  • 5.1结构型模式————代理模式

    在有些情况下 一个客户不能或者不想直接访问另一个对象 这时需要找一个中介帮忙完成某项任务 这个中介就是代理对象 例如 购买火车票不一定要去火车站买 可以通过 12306 网站或者去火车票代售点买 又如找女朋友 找保姆 找工作等都可以通过找中
  • 蓝翔:百度开源深度学习平台飞桨的核心技术及应用

    分享嘉宾 蓝翔 百度 资深研发工程师 编辑整理 张兰兰 人民银行 出品平台 DataFunTalk 导读 近期 DataFunSummit AI基础软件架构峰会以线上形式成功召开 其中深度学习框架论坛更是云集了各大著名科技企业的顶级专家 来
  • SpringMVC与Freemarker的集成以及多视图解析器配置

    一 Spring MVC视图解析器 视图解析器的工作流程大致是这样的 Controller的某个方法执行完成以后 返回一个视图 比如 listUser 视图解析器要做的工作就是找到某个对象 来完成视图的渲染 或者跳转到其他的逻辑视图 这里的