SpringMVC 里使用 Freemarker

JSP 和 Freemarker 都用于显示层,但是都有自己的优缺点。

Freemarker 的优点:
  1. 不能编写 Java 代码,可以实现严格的 MVC 分离,可维护性好
  2. 性能非常不错
  3. 对 JSP 标签支持良好
  4. 内置大量常用功能,使用非常方便
  5. 宏定义(类似 JSP 标签)非常方便
  6. 使用表达式语言
  7. 美工和技术的工作分离(例如命名为 .htm 的格式,不需要经过 Server 就能在浏览器里看到效果,JSP 这一点不太方便)
缺点:
  1. 不是官方标准
  2. 用户群体和第三方标签库没有 JSP 多

1. 在 pom.xml 中添加 Freemarker 的依赖

<!-- For Freemarker -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.20</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

2. 在 spring-mvc.xml 里添加 Freemarker 的配置

Order 值越小,查找 View 的优先级越高,如果找不到对应的 View,接着尝试下一个 order 值更高的视图解析器查找 View。

<!-- Freemarker 视图解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
   <property name="prefix" value=""/>
   <property name="order" value="0"/>
   <property name="cache" value="true"/>
   <property name="contentType" value="text/html; charset=UTF-8"/>
</bean>

<!-- Freemarker configuration -->
<!-- Freemarker 文件放在目录 WEB-INF/view/ftl 下 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
   <property name="templateLoaderPath" value="/WEB-INF/view/ftl/"/>
   <property name="freemarkerSettings">
       <props>
           <prop key="defaultEncoding">UTF-8</prop>
       </props>
   </property>
</bean>

3. 创建一个最简单的 Freemarker 的模版文件: /WEB-INF/view/ftl/helloworld-freemarker.htm

Username: ${username}<br>
Password: ${password}

项目目录结构如图

4. 在 HelloWorldController 里添加一个方法使用 Freemarker 解析器

    @RequestMapping("/helloworld-freemarker")
    public String helloFreemarker(ModelMap model) {
        // 放到 model 里的数据会在 Freemarker 模版文件里使用
        model.put("username", "Josh");
        model.put("password", "Passw0rd");

        // 当浏览器里访问 http://localhost:8080/helloworld-freemarker 时,
        // 访问的是 /WEB-INF/view/ftl/helloworld-freemarker.htm
        return "helloworld-freemarker.htm";
    }

5. 访问 http://localhost:8080/helloworld-freemarker

放到 model 里的数据显示出来了。