前言
在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
添加配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <tiles.version>3.0.4</tiles.version>
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <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>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer"> <property name="definitions"> <list> <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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <properties> <tiles.version>3.0.4</tiles.version> </properties>
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <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>
<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
内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?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> <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>
<definition name="empty" template="/templates/empty.jsp"> <put-attribute name="header" value="/templates/components/header.jsp" /> </definition>
<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页面一样,具体详见项目源码,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <%@ 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
添加配置如下:
1 2 3 4 5 6 7 8 9
| <properties> <freemarker.version>2.3.20</freemarker.version> </properties>
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency>
|
1. spring-mvc.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="contentNegotiationManager" ref="contentNegotiationManager"/> <property name="viewResolvers"> <list> <ref bean="beanNameViewResolver" /> <ref bean="freeMarkerViewResolver" /> </list> </property> <property name="defaultViews"> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/> </property> </bean>
<bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.freemarker.FreeMarkerView</value> </property> <property name="suffix" value=".html"/> <property name="cache" value="false" /> <property name="contentType" value="text/html;charset=utf-8"/> <property name="order" value="1"/> <property name="exposeRequestAttributes" value="true" /> <property name="exposeSessionAttributes" value="true" /> <property name="exposeSpringMacroHelpers" value="true" /> <property name="requestContextAttribute" value="rc"/> </bean>
<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"> <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.xml
和MainController.java
,这块需要注意!
web.xml
1 2 3 4
| <welcome-file-list> <welcome-file>/</welcome-file> </welcome-file-list>
|
MainController.java
1 2 3 4 5 6 7 8 9 10 11
|
@RequestMapping(value = "/", method = RequestMethod.GET) public String index(HttpServletRequest request, HttpServletResponse response) { return "index"; }
|
3. 组装FreeMarker页面
在SSM项目中配置FreeMarker模板引擎时,需要使用特定的指令来配置模板和组装页面组件,页面结构如下:
1 2 3 4 5 6 7 8 9 10 11
| |---[front-end](前端页面) |---|---index.html(登录页) |---|---welcome.html(首页) |---[tempaltes](模板文件) |---|---[components](模板组件) |---|---|---footer.html(页脚组件) |---|---|---header.html(页首组件) |---|---|---menu.html(菜单组件) |---|---|---nav-bar.html(导航栏组件) |---|---empty.html(没有菜单的主模板,如登录页使用) |---|---main.html(包含菜单和页脚的主模板,如首页使用)
|
具体配置方式如下:
empty.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <#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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <!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.html
和welcome.html
页面引用模板方式主要如下:
1 2 3 4 5 6 7 8 9 10 11
| <#import "templates/main.html" as main>
<@main.layout>
<h1>SSM框架整合笔记</h1> <hr> <div class="text-center"> <h4>~~欢迎关注下方微信公众号,记录javaweb常见的问题和相关技术,欢迎交流学习~~</h4> </div> </@main.layout>
|
至此,FreeMarker配置完成,详细注释和配置参考项目开头源码下载地址。
分享
欢迎扫描下方二维码,关注weyoung公众号,一起交流学习~~
更多联系方式