說明:剛剛接到公司的通知,實現(半自動化),即通過參數控制是否需要靜態化頁面(哪里我說錯了,勿噴!謝謝)
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);
文件目錄