SpringMVC+FreeMarker实现半自动静态化

 

 感谢imyourgod的原贴http://topic.csdn.net/u/20090613/12/30302a5d-33c0-4ce4-b9e3-cd503dbafac1.html
这里对freemarker的代码进行了修改,效果:
1,请求.do的URL时直接生成对应的.htm文件,并将请求转发到该htm文件
2,自由控制某个页面是否需要静态化

原理:对org.springframework.web.servlet.view.freemarker.FreeMarkerView类进行扩展

第一步:在web.xml中将*.do请求交给SpringMVC

XML code
    
< servlet > < servlet-name > demo </ servlet-name > < servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class > < init-param > < param-name > contextConfigLocation </ param-name > < param-value > /WEB-INF/demo-servlet.xml </ param-value > </ init-param > < load-on-startup > 1 </ load-on-startup > </ servlet > < servlet-mapping > < servlet-name > demo </ servlet-name > < url-pattern > *.do </ url-pattern > </ servlet-mapping >


第二步:配置/WEB-INF/demo-servlet.xml
XML code
    
<!-- freemarker页面解析器 --> < bean id ="viewResolver" class ="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" > < property name ="suffix" value =".ftl" ></ property > < property name ="contentType" value ="text/html;charset=UTF-8" /> <!-- <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> --> <!-- 将Spring的FreeMarkerView改成我们扩展的View --> < property name ="viewClass" value ="com.myview.MyFreeMarkerView" /> < 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 ="freemarkerConfigurer" class ="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" > < property name ="templateLoaderPath" value ="/WEB-INF/freemarker/" ></ property > < 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 ="defaultEncoding" > UTF-8 </ prop > </ props > </ property > </ bean >


第三步:新建package,com.myview,新建一个MyFreeMarkerView,继承自org.springframework.web.servlet.view.freemarker.FreeMarkerView,在这里对原类进行扩展
Java code
    
package com.myview; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Locale; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.support.RequestContextUtils; import org.springframework.web.servlet.view.freemarker.FreeMarkerView; import freemarker.template.SimpleHash; import freemarker.template.Template; import freemarker.template.TemplateException; public class MyFreeMarkerView extends FreeMarkerView{ @Override protected void doRender(Map < String, Object > model, HttpServletRequest request, HttpServletResponse response) throws Exception { // Expose model to JSP tags (as request attributes). exposeModelAsRequestAttributes(model, request); // Expose all standard FreeMarker hash models. SimpleHash fmModel = buildTemplateModel(model, request, response); if (logger.isDebugEnabled()) { logger.debug( " Rendering FreeMarker template [ " + getUrl() + " ] in FreeMarkerView ' " + getBeanName() + " ' " ); } // Grab the locale-specific version of the template. Locale locale = RequestContextUtils.getLocale(request); /* * 默认生成静态文件,除非在编写ModelAndView时指定CREATE_HTML = false, * 这样对静态文件生成的粒度控制更细一点 * 例如:ModelAndView mav = new ModelAndView("search"); * mav.addObject("CREATE_HTML", false); */ if (Boolean.FALSE.equals(model.get( " CREATE_HTML " ))){ processTemplate(getTemplate(locale), fmModel, response); } else { createHTML(getTemplate(locale), fmModel, request, response); } } public void createHTML(Template template, SimpleHash model,HttpServletRequest request, HttpServletResponse response) throws IOException, TemplateException, ServletException { // 站点根目录的绝对路径 String basePath = request.getSession().getServletContext().getRealPath( " / " ); String requestHTML = this .getRequestHTML(request); // 静态页面绝对路径 String htmlPath = basePath + requestHTML; File htmlFile = new File(htmlPath); if ( ! htmlFile.getParentFile().exists()){ htmlFile.getParentFile().mkdirs(); } if ( ! htmlFile.exists()){ htmlFile.createNewFile(); } Writer out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(htmlFile), " UTF-8 " )); // 处理模版 template.process(model, out); out.flush(); out.close(); /* 将请求转发到生成的htm文件 */ request.getRequestDispatcher(requestHTML).forward(request, response); } /** * 计算要生成的静态文件相对路径 * 因为大家在调试的时候一般在Tomcat的webapps下面新建站点目录的, * 但在实际应用时直接布署到ROOT目录里面,这里要保证路径的一致性。 * @param request HttpServletRequest * @return /目录/*.htm */ private String getRequestHTML(HttpServletRequest request){ // web应用名称,部署在ROOT目录时为空 String contextPath = request.getContextPath(); // web应用/目录/文件.do String requestURI = request.getRequestURI(); // basePath里面已经有了web应用名称,所以直接把它replace掉,以免重复 requestURI = requestURI.replaceFirst(contextPath, "" ); // 将.do改为.htm,稍后将请求转发到此htm文件 requestURI = requestURI.substring( 0 , requestURI.indexOf( " . " )) + " .htm " ; return requestURI; } }


到这里就基本完成了。
一个Controller类的例子:
Java code
    
package com.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class IndexController { @RequestMapping( " /index " ) public ModelAndView index(){ ModelAndView mav = new ModelAndView( " index " ); mav.addObject( " title " , " 网站标题 " ); // 在这里可以控制不生成静态htm mav.addObject( " CREATE_HTML " , false ); return mav; } @RequestMapping( " /abc/index " ) public ModelAndView abcindex(){ ModelAndView mav = new ModelAndView( " index " ); // 默认生成htm文件 mav.addObject( " title " , " 网站标题 " ); return mav; } }

你可能感兴趣的:(spring,freemarker,springMVC)