SpringMVC中使用FreeMarker实践

简介: SpringMVC中使用FreeMarker实践

使用RESTful风格,故需要额外注意DispatcherServlet的url-pattern和applicationContext.xml中的配置。

<mvc:default-servlet-handler/>

【1】applicationContext.xml配置

applicationContext.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context" 
   xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:aop="http://www.springframework.org/schema/aop"
  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/tx   http://www.springframework.org/schema/tx/spring-tx.xsd
                            http://www.springframework.org/schema/mvc   http://www.springframework.org/schema/mvc/spring-mvc.xsd
                          http://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com" />
  <mvc:annotation-driven />
  <mvc:default-servlet-handler/>
<!-- 配置freemarker -->
 <bean id="freemarkerConfigurer"  
     class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
   <property name="templateLoaderPath" value="/WEB-INF/views/" /> 
   <!--<property name="freemarkerSettings" ref="freemarkerConfiguration"/> -->
     <property name="freemarkerSettings">  
         <props>  
          <!-- 禁用freemarker缓存 -->
             <prop key="template_update_delay">0</prop>  
             <prop key="default_encoding">UTF-8</prop>
             <prop key="url_escaping_charset">UTF-8</prop>   
             <prop key="locale">zh_CN</prop>  
             <prop key="localized_lookup">false</prop>
             <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>  
             <prop key="date_format">yyyy-MM-dd</prop>
             <prop key="time_format">HH:mm:ss</prop>
             <prop key="boolean_format">true,false</prop>    
             <prop key="number_format">#.##</prop>  //设置数字格式化,不被逗号隔开
         </props>  
     </property>
     <!--这里设置需要配置的变量-->
     <property name="freemarkerVariables">  
         <map>  
             <entry key="xml_escape" value-ref="fmXmlEscape" />  
         </map>  
   </property>  
 </bean>
 <!--这里配置xml转译工具类-->
 <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />  
<!-- 如果属性配置在properties文件中,可使用如下代码(上面的freemarkerSettings可配置在properties文件中) -->
<!--     <bean id="freemarkerConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">  
     <property name="location" value="classpath:freemarker.properties" />  
 </bean>  
-->
<!-- freemarker配置视图解析器 -->
 <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
  <!-- 禁用SpringMVC缓存 -->
     <property name="cache" value="false" />
     <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
     <!-- 扫描路径內所有以ftl結尾的文件 viewNames 和suffix 只能存在一个 -->  
<!--         <property name="viewNames">   -->
<!--             <array>   -->
<!--                 <value>*.ftl</value>   -->
<!--             </array>   -->
<!--         </property> -->
     <property name="suffix" value=".ftl" />
     <property name="contentType" value="text/html;charset=UTF-8"/>
     <property name="requestContextAttribute" value="request" />
     <property name="exposeSpringMacroHelpers" value="true" />
     <property name="exposeRequestAttributes" value="true" />
     <property name="exposeSessionAttributes" value="true" />
 </bean>
</beans>

【2】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" xmlns:web="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"
  version="3.0">
  <filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <servlet-name>hh-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <param-name>namespace</param-name>
      <param-value>hh-mvc</param-value>
    </init-param>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:applicationContext.xml</param-value>
    </init-param>
    <init-param>
      <param-name>publishContext</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>hh-mvc</servlet-name>
    <!-- 注意这里 -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

【3】测试实例

① 后台代码

package com.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@RequestMapping("/data")
@Controller
public class DataController {
  @RequestMapping("/hello")
  public ModelAndView hello(){
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg", "hello world !");
    mv.setViewName("hello");
    return mv;
  }
}

② FTL模板

<#assig<#assign base=request.contextPath/>
<!DOCTYPE html>
<html>
<head>
  <base id="base" href="${base}">
  <meta charset="UTF-8">
  <title>hello ftl</title>
<script type="text/javascript">
  var base = document.getElementById("base").href;
  console.log(base);
</script>
</head>
<body>
  ${msg}
</body>
</html>

【4】XmlEscape

对给定的模板片段执行XML转义,此转换的实例最初作为共享变量xml_escape可见。即,其他地方使用xml_escape变量来引用该实例。


其源码如下:

package freemarker.template.utility;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import freemarker.template.TemplateTransformModel;
/**
 * Performs an XML escaping of a given template fragment. Specifically,
 * <tt>&lt;</tt> <tt>&gt;</tt> <tt>&quot;</tt> <tt>'</tt> and <tt>&amp;</tt> are all turned into entity references.
 *
 * <p>An instance of this transform is initially visible as shared
 * variable called <tt>xml_escape</tt>.</p>
 */
public class XmlEscape implements TemplateTransformModel {
    private static final char[] LT = "&lt;".toCharArray();
    private static final char[] GT = "&gt;".toCharArray();
    private static final char[] AMP = "&amp;".toCharArray();
    private static final char[] QUOT = "&quot;".toCharArray();
    private static final char[] APOS = "&apos;".toCharArray();
    public Writer getWriter(final Writer out, Map args)
    {
        return new Writer()
        {
            public void write(int c)
            throws
                IOException
            {
                switch(c)
                {
                    case '<': out.write(LT, 0, 4); break;
                    case '>': out.write(GT, 0, 4); break;
                    case '&': out.write(AMP, 0, 5); break;
                    case '"': out.write(QUOT, 0, 6); break;
                    case '\'': out.write(APOS, 0, 6); break;
                    default: out.write(c);
                }
            }
            public void write(char cbuf[], int off, int len)
            throws
                IOException
            {
                int lastoff = off;
                int lastpos = off + len;
                for (int i = off; i < lastpos; i++)
                {
                    switch (cbuf[i])
                    {
                        case '<': out.write(cbuf, lastoff, i - lastoff); out.write(LT, 0, 4); lastoff = i + 1; break;
                        case '>': out.write(cbuf, lastoff, i - lastoff); out.write(GT, 0, 4); lastoff = i + 1; break;
                        case '&': out.write(cbuf, lastoff, i - lastoff); out.write(AMP, 0, 5); lastoff = i + 1; break;
                        case '"': out.write(cbuf, lastoff, i - lastoff); out.write(QUOT, 0, 6); lastoff = i + 1; break;
                        case '\'': out.write(cbuf, lastoff, i - lastoff); out.write(APOS, 0, 6); lastoff = i + 1; break;
                    }
                }
                int remaining = lastpos - lastoff;
                if(remaining > 0)
                {
                    out.write(cbuf, lastoff, remaining);
                }
            }
            public void flush() throws IOException {
                out.flush();
            }
            public void close() {
            }
        };
    }
}
目录
相关文章
|
设计模式 前端开发 Java
SpringMVC系列(一)之SpringMVC入门详细介绍
SpringMVC系列(一)之SpringMVC入门详细介绍
|
6月前
|
前端开发 Java 应用服务中间件
|
6月前
|
JSON 前端开发 Java
SpringMVC(一)【入门】
SpringMVC(一)【入门】
|
7月前
|
缓存
FreeMarker实践总结
FreeMarker实践总结
71 1
|
XML 前端开发 Java
SpringMVC之入门
SpringMVC之入门
61 0
|
关系型数据库 MySQL 数据库
42SpringMVC - SpringMVC小案例
42SpringMVC - SpringMVC小案例
32 0
|
前端开发 Java 应用服务中间件
SpringMVC学习
SpringMVC学习
57 0
|
前端开发 Java 应用服务中间件
一文带你入门SpringMVC
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。 Spring MVC的特点: 轻量级,简单易学 高效 , 基于请求响应的MVC框架 与Spring兼容性好,无缝结合 约定优于配置 功能强大:RESTful、数据验证、格式化、本地化、主题等 简洁灵活
136 1
一文带你入门SpringMVC
|
前端开发 Java 测试技术
springMVC学习总结
springMVC学习总结
126 0
springMVC学习总结
|
设计模式 JSON 缓存