SSM框架整合笔记(三)视图解析器Tiles、FreeMarker配置

3 篇文章 0 订阅
3 篇文章 0 订阅

前言

  在MVC开发模式下,View离不开模板引擎,在Java中模板引擎使用最多的就是JSP、Velocity和FreeMarker。在配置框架的过程中,一般的系统中的前端页面中总是有一些通用的头部、底部或者菜单栏,最原始的方法当然是为每个HTML页面添加需要引入的css或者js等公用资源,但是这种方式似乎太难以维护。使用JSP的话,尽管JSP存在的时间很长、也特别像HTML,但是由于夹杂了各种标签库,显得特别混乱,因此在传统的单机应用中,在了解了常用的几个前端模板引擎(视图解析器),如Freemarker、Thymeleaf、Velocity、Tiles等:

  • Velocity:自面世以来就以语法简单著称,其写法非常接近Java语法,学习成本低,而且其简单的语法给开发人员带来了很大的自由度,能够自由发挥;
  • FreeMarker: 使用后缀为ftl(FreeMarker Template Language,FTL)和html 的模板,处理动态网页优势比较强,由于不能写Java代码,可以实现严格的MVC分离;
  • Thymeleaf: 该模板会改变普通HTML的写法,需要在HTML中添加一些属性,能够按照原始的方式进行编辑甚至渲染,而不必经过任何类型的处理器;
  • JSP: JSP不是真正的HTML,但是JSP规范和Servlet规范是紧密耦合的,这也限制了它只能用在基于Servlet的Web应用之中。
  • Tiles:Apache Tiles,定义适用于所有页面的通用页面布局。但是Tiles的模板是需要和jsp结合的,内容页和模板页是独立的页面,因此不会影响HTML内容页的写法。

本文内容:使用Tiles、FreeMarker配置前端模板引擎。

相关文章

demo下载地址

该项目持续更新中,会在代码以及该文档里面详细注释和介绍。
项目托管在码云开源平台上,持续更新项目源码链接:

https://gitee.com/nelucifer/ssm-note,点击克隆/下载获取该项目。

本文描述的项目版本为v1.0.1,版本源码链接:
https://gitee.com/nelucifer/ssm-note/releases/v1.0.1

注意:如果项目代码内容有变化和本例不太一样的话,请查看项目标签,标签会具体说明,使用方式如下:

本文内容

在一个项目中可以配置多个视图解析器,如Tiles、FreeMarker等可以同时配置,为了使得模板简洁和统一,本文仅介绍Tiles和FreeMarker的单独配置。

  • 一、XML方式配置Tiles;
  • 二、配置FreeMarker模板引擎;
  • 三、FreeMarker拆分和复用页面;

一、配置Tiles

0. pom.xml引入依赖

pom.xml添加配置如下:

<!--<properties>-->
    <tiles.version>3.0.4</tiles.version>
<!--</properties>-->
<!-- tiles -->
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-extras</artifactId>
        <version>${tiles.version}</version>
        <exclusions>
            <exclusion>
                <artifactId>commons-beanutils</artifactId>
                <groupId>commons-beanutils</groupId>
            </exclusion>
            <exclusion>
                <artifactId>jcl-over-slf4j</artifactId>
                <groupId>org.slf4j</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-servlet</artifactId>
        <version>${tiles.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-jsp</artifactId>
        <version>${tiles.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-core</artifactId>
        <version>${tiles.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-api</artifactId>
        <version>${tiles.version}</version>
    </dependency>

1. spring-mvc.xml

    <!--spring-mvc 视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver"/>

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
        <property name="defaultViews">
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
        </property>
    </bean>

    <!-- 模板引擎Tiles -->
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
        <property name="definitions">
            <list>
            <!-- tiles的模板组件组装配置 -->
                <value>/WEB-INF/views/*-tiles.xml</value>
            </list>
        </property>
    </bean>

2. 创建Tiles模板组件

分析下我们要展示的页面内容,具体布局如下图:
其中 header、nav-bar、menu、content(body)、footer可以提取出来,如下:

  • header: 主要用来引入外部文件【header.jsp】;
  • nav-bar:主要用来添加导航栏【nav-bar.jsp】;
  • menu: 菜单模块【menu.jsp】;
  • content: 内容模块,是页面主体【动态添加的内容】;
  • footer: 底部声明等【footer.jsp】;

具体思路如下,首先在pom.xml添加Tiles的相关依赖,在spring-mvc.xml中添加视图解析器的配置,在default-tiles.xml中组装主模板和各个页面,即可。详细步骤如下:

1. pom.xml
    <properties>
        <tiles.version>3.0.4</tiles.version>
    </properties>
    <!-- Apache Tiles -->
    <dependency>
      <groupId>org.apache.tiles</groupId>
      <artifactId>tiles-extras</artifactId>
      <version>${tiles.version}</version>
      <exclusions>
        <exclusion>
          <artifactId>commons-beanutils</artifactId>
          <groupId>commons-beanutils</groupId>
        </exclusion>
        <exclusion>
          <artifactId>jcl-over-slf4j</artifactId>
          <groupId>org.slf4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.apache.tiles</groupId>
      <artifactId>tiles-servlet</artifactId>
      <version>${tiles.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tiles</groupId>
      <artifactId>tiles-jsp</artifactId>
      <version>${tiles.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tiles</groupId>
      <artifactId>tiles-core</artifactId>
      <version>${tiles.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tiles</groupId>
      <artifactId>tiles-api</artifactId>
      <version>${tiles.version}</version>
    </dependency>
2. spring-mvc.xml
    <!-- tiles视图解释器 -->
    <bean id="tilesViewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
        <property name="order" value="1"></property>
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
    </bean>

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
        <!-- 视图解析器 -->
        <property name="viewResolvers">
            <list>
                <ref bean="beanNameViewResolver" />
                <ref bean="tilesViewResolver" />
            </list>
        </property>
        <property name="defaultViews">
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
        </property>
    </bean>

    <!-- 模板引擎Tiles配置 -->
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/views/*-tiles.xml</value>
            </list>
        </property>
        <property name="preparerFactoryClass" value="org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory" />
    </bean>
3. 组装各页面组件

default-tiles.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
        "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
        "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">

<tiles-definitions>
    <!-- 定义base Tile,主布局 -->
    <definition name="base" template="/templates/base.jsp">
        <!-- 定义属性 -->
        <put-attribute name="header" value="/templates/components/header.jsp" />
        <put-attribute name="nav" value="/templates/components/nav-bar.jsp" />
        <put-attribute name="menu" value="/templates/components/menu.jsp" />
        <put-attribute name="content" value="" />
        <put-attribute name="footer" value="/templates/components/footer.jsp" />
    </definition>

    <!-- 定义base Tile -->
    <definition name="empty" template="/templates/empty.jsp">
        <!-- 定义属性 -->
        <put-attribute name="header" value="/templates/components/header.jsp" />
    </definition>

    <!-- 扩展base Tile -->
    <definition name="/home" extends="base">
        <put-attribute name="content" value="/front-end/welcome.jsp" />
    </definition>
    <!-- 登录页 -->
    <definition name="/login" extends="empty">
        <put-attribute name="content" value="/front-end/system/index.jsp" />
    </definition>
</tiles-definitions>
4. 主页面 base.jsp

以下为主页面模板配置,引入的其他页面和其他jsp页面一样,具体详见项目源码,内容如下:

<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%--
  Created by IntelliJ IDEA.
  Description: 该模板就是包含所有的模板(有导航栏、菜单栏、内容、页脚)
  User: Mr.wang
  Date: 2017/6/21
  Time: 22:18
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
          content="width=device-width, initial-scale=1,user-scalable=no">
    <meta name="format-detection" content="telephone=no"/>
    <tiles:insertAttribute name="header"/>
    <style>
        自定义样式...
    </style>
</head>
<body class="scroll-bar hold-transition skin-blue sidebar-mini">
<div class="wrapper">
    <div>
        <header class="main-header">
            <tiles:insertAttribute name="nav"/>
        </header>
        <aside class="main-sidebar">
            <tiles:insertAttribute name="menu"/>
        </aside>
        <section id="lucifer_content" class="content-wrapper">
            <tiles:insertAttribute name="content"/>
        </section>
        <div class="navbar-fixed-bottom">
            <footer class="main-footer" style="margin-left: 260px">
                <tiles:insertAttribute name="footer"/>
            </footer>
        </div>
    </div>
</div>
</body>
</html>

二、配置FreeMarker模板引擎

0. pom.xml引入依赖

pom.xml添加配置如下:

    <properties>
        <freemarker.version>2.3.20</freemarker.version>
    </properties>
    <!-- FreeMarker -->
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>${freemarker.version}</version>
    </dependency>

1. spring-mvc.xml

    <!--spring-mvc 视图解析器-->
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
        <!-- 视图解析器 -->
        <property name="viewResolvers">
            <list>
                <ref bean="beanNameViewResolver" />
                <!-- 模板引擎中添加FreeMarker配置 -->
                <ref bean="freeMarkerViewResolver" />
            </list>
        </property>
        <property name="defaultViews">
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
        </property>
    </bean>
    <!-- FreeMarker 模板引擎 -->
    <bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="viewClass">
            <value>org.springframework.web.servlet.view.freemarker.FreeMarkerView</value>
        </property>
        <!-- 识别为FreeMarker页面的文件后缀 -->
        <property name="suffix" value=".html"/>
        <property name="cache" value="false" />
        <property name="contentType" value="text/html;charset=utf-8"/>
        <property name="order" value="1"/>
        <!-- 在FreeMarker页面中使用request对象 -->
        <property name="exposeRequestAttributes" value="true" />
        <property name="exposeSessionAttributes" value="true" />
        <property name="exposeSpringMacroHelpers" value="true" />
        <property name="requestContextAttribute" value="rc"/>
    </bean>

    <!-- FreeMarker 模板引擎配置 -->
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPaths">
            <list>
                <value>/front-end</value>
                <value>/</value>
            </list>
        </property>
        <property name="defaultEncoding" value="utf-8"/>
        <property name="freemarkerSettings"><!-- 设置FreeMarker环境属性 -->
            <props>
                <prop key="template_update_delay">5</prop><!--刷新模板的周期,单位为秒 -->
                <prop key="default_encoding">UTF-8</prop><!--模板的编码格式 -->
                <prop key="locale">zh_CN</prop><!-- 本地化设置,设置默认地区 -->
                <prop key="template_exception_handler">rethrow</prop>
                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                <prop key="time_format">HH:mm:ss</prop>
                <prop key="number_format">#.####</prop><!-- 设置默认数字输出格式 -->
                <prop key="boolean_format">true,false</prop><!-- 设置默认布尔值输出格式 -->
                <prop key="whitespace_stripping">true</prop>
                <prop key="tag_syntax">auto_detect</prop>
                <prop key="url_escaping_charset">UTF-8</prop>
            </props>
        </property>
    </bean>

2. web.xml

注意: FreeMarker配置首页为html页面的话,需要进行特别的配置,需要修改web.xml中设置的登录页,否则直接配置index.html的话会导致页面中的FreeMarker配置无效,因此需修改web.xmlMainController.java,这块需要注意!

web.xml

<!-- 默认进入页面,一般为登录页 -->
  <welcome-file-list>
    <welcome-file>/</welcome-file>
  </welcome-file-list>

MainController.java

    /**
     * @Author Mr.wang
     * @Description // 登录页,控制启动时跳转
     * @Date 2019/3/2 23:39
     * @Param [request, response]
     * @return
     **/
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(HttpServletRequest request, HttpServletResponse response) {
        return "index";
    }

3. 组装FreeMarker页面

在SSM项目中配置FreeMarker模板引擎时,需要使用特定的指令来配置模板和组装页面组件,页面结构如下:

|---[front-end](前端页面)
|---|---index.html(登录页)
|---|---welcome.html(首页)
|---[tempaltes](模板文件)
|---|---[components](模板组件)
|---|---|---footer.html(页脚组件)
|---|---|---header.html(页首组件)
|---|---|---menu.html(菜单组件)
|---|---|---nav-bar.html(导航栏组件)
|---|---empty.html(没有菜单的主模板,如登录页使用)
|---|---main.html(包含菜单和页脚的主模板,如首页使用)

具体配置方式如下:

empty.html

<#macro empty>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Pragma" content="no-cache">
    <#include "../templates/components/header.html">
    <style>
        自定义的样式
    </style>
</head>
<body>
<!-- 插入内容页 -->
<#nested>
</body>
</html>
</#macro>

empty.html

<!DOCTYPE html>
<#macro layout>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Pragma" content="no-cache">
    <#include "../templates/components/header.html">
    <style>
       自定义的样式
    </style>
</head>
<body class="scroll-bar hold-transition skin-blue sidebar-mini">
<div class="wrapper">
    <div>
        <header class="main-header">
            <#include "../templates/components/nav-bar.html">
        </header>
        <aside class="main-sidebar">
            <#include "../templates/components/menu.html">
        </aside>
        <section id="lucifer_content" class="content-wrapper">
            <!-- 在这里嵌入主题内容 -->
            <#nested>
        </section>
        <div class="navbar-fixed-bottom">
            <footer class="main-footer" style="margin-left: 260px">
                <#include "../templates/components/footer.html">
            </footer>
        </div>
    </div>
</div>
</body>
<script>
    var InitFrame = (function () {
        var setTitle = function (title) {
            title && $(document).attr("title", title)
        };
        return {setTitle: setTitle};
    })()
    InitFrame.setTitle("SSM框架整合");
</script>
</html>
</#macro>

index.htmlwelcome.html页面引用模板方式主要如下:

<!-- 引入布局指令的命名空间 -->
<#import "templates/main.html" as main>
<!-- 调用布局指令 -->
<@main.layout>
<!-- 下面的这些内容会自动嵌入到layout指令的nested块中 -->
<h1>SSM框架整合笔记</h1>
<hr>
<div class="text-center">
    <h4>~~欢迎关注下方微信公众号,记录javaweb常见的问题和相关技术,欢迎交流学习~~</h4>
</div>
</@main.layout>

至此,FreeMarker配置完成,详细注释和配置参考项目开头源码下载地址。

分享

欢迎扫描下方二维码,关注weyoung公众号,一起交流学习~~

更多联系方式

平台链接
预览项目:https://nelucifer.gitee.io/
个人微信公众号:weyoung
segmentfault:https://segmentfault.com/u/nelucifer
CSDN:https://me.csdn.net/wlx001
简书:https://www.jianshu.com/u/99211cc23788
掘金:https://juejin.im/user/59b08c575188250f4850e80e
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值