1,请求.do的URL时直接生成对应的.htm文件,并将请求转发到该htm文件
2,自由控制某个页面是否需要静态化
如果看图不懂的呢,说白了这个中技术就是:java对象+ftl模型=输出html视图
1、在sprinMVC中:MVC框架中的View层组件、Html页面静态化、代码生成工具
2、为什么要用FreeMarker:简单容易学、逻辑分离明确
3、FreeMarker优点:FreeMarker不依赖于Servlet,网络或Web 环境(没一毛钱关系)
maven
1 <dependency>
2 <groupId>org.freemarker</groupId>
3 <artifactId>freemarker</artifactId>
4 <version>2.3.20</version>
5 </dependency>
6 <dependency>
7 <groupId>freemarker</groupId>
8 <artifactId>freemarker</artifactId>
9 <version>2.3.8</version>
10 </dependency>
11 <dependency>
12 <groupId>org.springframework</groupId>
13 <artifactId>spring-context-support</artifactId>
14 <version>4.2.4.RELEASE</version>
15 </dependency>
一、web.xml配置(配置大部分都一样)
二、在springMVC文件中配置freemarker视图解析器
<!--FreeMarker视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=UTF-8"></property>
<property name="viewClass" value="com.freemarker.Controller.FreeMarkerViewUtil" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />
<!-- Freemarker配置 -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/view/" />
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape" />
</map>
</property>
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">1</prop>
<prop key="default_encoding">UTF-8</prop>
<prop key="number_format">0.##########</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="classic_compatible">true</prop>
<prop key="template_exception_handler">ignore</prop>
</props>
</property>
</bean>
三、建立模型文件(freemarker完全支持el表达式语言)
我的目录是:WebContent/WEB-INF/view/index.ftl,建立一个文件后缀为ftl即可!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>演示${title}</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<#list users as user>
测试..............username : ${user.username}
测试..............password : ${user.password}
</#list>
</body>
</html>
四、编写视图解析器(FreeMarkerViewUtil.java),继承自org.springframework.web.servlet.view.freemarker.FreeMarkerView在这里对原类进行扩展
1 package com.freemarker.Controller;
2
3 import java.io.BufferedWriter;
4 import java.io.File;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.OutputStreamWriter;
8 import java.io.Writer;
9 import java.util.Locale;
10 import java.util.Map;
11 import javax.servlet.ServletException;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import org.springframework.web.servlet.support.RequestContextUtils;
15 import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
16 import freemarker.template.SimpleHash;
17 import freemarker.template.Template;
18 import freemarker.template.TemplateException;
19
20 public class FreeMarkerViewUtil extends FreeMarkerView {
21 @Override
22 protected void doRender(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)
23 throws Exception {
24 // Expose model to JSP tags (as request attributes).
25 exposeModelAsRequestAttributes(model, request);
26 // Expose all standard FreeMarker hash models.
27 SimpleHash fmModel = buildTemplateModel(model, request, response);
28
29 if (logger.isDebugEnabled()) {
30 logger.debug("Rendering FreeMarker 模版 [" + getUrl() + "] in FreeMarkerView '" + getBeanName() + "'");
31 }
32 // Grab the locale-specific version of the template.
33 Locale locale = RequestContextUtils.getLocale(request);
34
35 /*
36 * 默认生成静态文件,除非在编写ModelAndView时指定CREATE_HTML = false, 这样对静态文件生成的粒度控制更细一点
37 * 例如:ModelAndView mav = new ModelAndView("search");
38 * mav.addObject("CREATE_HTML", false);
39 */
40 if (Boolean.FALSE.equals(model.get("CREATE_HTML"))) {
41 processTemplate(getTemplate(locale), fmModel, response);
42 } else {
43 createHTML(getTemplate(locale), fmModel, request, response);
44 }
45 }
46
47 public void createHTML(Template template, SimpleHash model, HttpServletRequest request,
48 HttpServletResponse response) throws IOException, TemplateException, ServletException {
49 // 站点根目录的绝对路径
50 String basePath = request.getSession().getServletContext().getRealPath("/");
51 String requestHTML = this.getRequestHTML(request);
52 // 静态页面绝对路径
53 String htmlPath = basePath + requestHTML;
54 System.out.println("静态页面绝对路径===========>>:"+htmlPath);
55 File htmlFile = new File(htmlPath);
56 if (!htmlFile.getParentFile().exists()) {
57 htmlFile.getParentFile().mkdirs();
58 }
59 if (!htmlFile.exists()) {
60 htmlFile.createNewFile();
61 }
62 Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
63 // 处理模版
64 template.process(model, out);
65 out.flush();
66 out.close();
67 /* 将请求转发到生成的htm文件 */
68 request.getRequestDispatcher(requestHTML).forward(request, response);
69 }
70
71 /**
72 * 计算要生成的静态文件相对路径 因为大家在调试的时候一般在Tomcat的webapps下面新建站点目录的,
73 * 但在实际应用时直接布署到ROOT目录里面,这里要保证路径的一致性。
74 *
75 * @param request
76 * HttpServletRequest
77 * @return /目录/*.htm
78 */
79 private String getRequestHTML(HttpServletRequest request) {
80 // web应用名称,部署在ROOT目录时为空
81 String contextPath = request.getContextPath();
82 // web应用/目录/文件.do
83 String requestURI = request.getRequestURI();
84 // basePath里面已经有了web应用名称,所以直接把它replace掉,以免重复
85 requestURI = requestURI.replaceFirst(contextPath, "");
86 // 将.do改为.html,稍后将请求转发到此html文件
87 requestURI = requestURI.substring(0, requestURI.indexOf(".")) + ".html";
88 return requestURI;
89 }
90 }
五、测试类(Controller)
1 package com.freemarker.Controller;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.servlet.http.HttpServletRequest;
7 import javax.servlet.http.HttpServletResponse;
8 import org.springframework.stereotype.Controller;
9 import org.springframework.web.bind.annotation.RequestMapping;
10 import org.springframework.web.servlet.ModelAndView;
11 import com.spring.vo.User;
12
13 @Controller
14 @RequestMapping("/home")
15 public class FreeMarkerController {
16
17 @RequestMapping("index1")
18 public ModelAndView Add(HttpServletRequest request, HttpServletResponse response) {
19 ModelAndView mav = new ModelAndView("index");
20 User user = new User();
21 user.setUsername("<h2>小明=========================================================></h2>");
22 user.setPassword("<a href='https://www.hao123.com/'>百度</a>");
23 List<User> users = new ArrayList<User>();
24 users.add(user);
25 mav.addObject("users", users);
26 return mav;
27 }
28
29 @RequestMapping("index2")
30 public ModelAndView index() {
31 ModelAndView mav = new ModelAndView("index");
32 mav.addObject("title", "网站标题");
33 //说明:在这里可以控制不生成静态htm
34 mav.addObject("CREATE_HTML", false);
35 return mav;
36 }
37 }
访问:http://localhost:1010/springMVC_FreeMarker/home/index1.do,访问index1.do才会生成html文件,生成的html文件是根据@RequestMapping("index1")name决定的.
如果不需要生成静态化页面
mav.addObject("CREATE_HTML", false);
文件目录