Spring mvc系列八之 页面静态化(二)

来源:互联网 发布:js 加密算法 编辑:程序博客网 时间:2024/06/08 18:21

前一章讲到页面静态化当中freeMarker标签的使用,这一章我们使用spring mvc结合freeMarker处理大型网站页面静态化.

第一步:引入除spring mvc 所需的jar包(之前系列的文章讲过,大家可以看之前的文章),还需要引入freemarker-xxx.jar commons-logging-xxx.jar  

 

第二步:扩展FreeMarkerView,使我们可以控制是否生成静态页面以及生成的静态页面存放的位置.

Java代码  收藏代码
  1. package gd.hz;  
  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.   
  12. import javax.servlet.ServletException;  
  13. import javax.servlet.http.HttpServletRequest;  
  14. import javax.servlet.http.HttpServletResponse;  
  15.   
  16. import org.springframework.web.servlet.support.RequestContextUtils;  
  17. import org.springframework.web.servlet.view.freemarker.FreeMarkerView;  
  18.   
  19. import freemarker.template.SimpleHash;  
  20. import freemarker.template.Template;  
  21. import freemarker.template.TemplateException;  
  22.   
  23. public class ExFreeMarkerView extends FreeMarkerView {  
  24.      @Override  
  25.         protected void doRender(Map<String, Object> model,  
  26.                 HttpServletRequest request, HttpServletResponse response)  
  27.                 throws Exception {  
  28.            
  29.             exposeModelAsRequestAttributes(model, request);  
  30.               
  31.             SimpleHash fmModel = buildTemplateModel(model, request, response);  
  32.        
  33.             if (logger.isDebugEnabled()) {  
  34.                 logger.debug("Rendering FreeMarker template [" + getUrl() + "] in FreeMarkerView '" + getBeanName() + "'");  
  35.             }  
  36.               
  37.             Locale locale = RequestContextUtils.getLocale(request);  
  38.                
  39.             /* 
  40.              * 在这里我们默认生成静态文件,当ModelAndView有指定STATIC_HTML = false时,就不会输出HTML文件 
  41.              * 例如:ModelAndView modelAndView = new ModelAndView("htmlTest"); 
  42.              *       modelAndView.addObject("STATICHTML", false);  
  43.              */  
  44.             if(Boolean.FALSE.equals(model.get("STATIC_HTML"))){  
  45.                 processTemplate(getTemplate(locale), fmModel, response);  
  46.             }else{  
  47.                 createHTML(getTemplate(locale), fmModel, request, response);  
  48.             }  
  49.         }  
  50.        
  51.         public void createHTML(Template template, SimpleHash model,HttpServletRequest request,  
  52.                 HttpServletResponse response) throws IOException, TemplateException, ServletException {  
  53.                 //站点根目录的绝对路径  
  54.                 String basePath = request.getSession().getServletContext().getRealPath("/");  
  55.                 String requestHTML = this.getRequestHTML(request);  
  56.                   
  57.                 //静态页面绝对路径  
  58.                 String htmlPath = basePath + requestHTML;  
  59.                    
  60.                 File htmlFile = new File(htmlPath);  
  61.                   
  62.                 if(!htmlFile.getParentFile().exists()){  
  63.                     htmlFile.getParentFile().mkdirs();  
  64.                 }  
  65.                   
  66.                 /** 
  67.                  * 如果静态页面已经存在,就不再创建静态页面. 
  68.                  */  
  69.                 if(!htmlFile.exists()){  
  70.                     htmlFile.createNewFile();  
  71.                     Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));  
  72.                     //处理模版    
  73.                     template.process(model, out);  
  74.                     out.flush();  
  75.                     out.close();  
  76.                 }  
  77.                 /*将请求转发到生成的htm文件*/  
  78.                 request.getRequestDispatcher(requestHTML).forward(request, response);  
  79.         }  
  80.            
  81.         /** 
  82.          * 计算要生成的静态文件相对路径. 
  83.          */  
  84.         private String getRequestHTML(HttpServletRequest request){  
  85.               
  86.             //web应用名称,部署在ROOT目录时为空  
  87.             String contextPath = request.getContextPath();  
  88.               
  89.             //web应用/目录/文件.do  
  90.             String requestURI = request.getRequestURI();  
  91.               
  92.             //basePath里面已经有了web应用名称,所以直接把它replace掉,以免重复  
  93.             requestURI = requestURI.replaceFirst(contextPath, "");  
  94.              
  95.             //将.do改为.htm,稍后将请求转发到此htm文件  
  96.             requestURI = requestURI.substring(0, requestURI.indexOf(".")) + ".htm";  
  97.                
  98.             return requestURI;  
  99.         }  
  100. }  

 这里我们取出STATIC_HTML的值,当为false是就不生成静态页面.

而getRequestHTML()方法是生成静态页面的相对路径,这里我们可以灵活处理,可以决定静态页面的存放路径.

 

第三步:配置spring mvc配置文件,这里我的文件名为springmvc.xml

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.     xsi:schemaLocation="        
  7.            http://www.springframework.org/schema/beans        
  8.            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd        
  9.            http://www.springframework.org/schema/context        
  10.            http://www.springframework.org/schema/context/spring-context-3.0.xsd       
  11.            http://www.springframework.org/schema/mvc        
  12.            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  13.     <!-- 开启注解扫描功能 -->  
  14.     <context:component-scan base-package="gd.hz.controller"></context:component-scan>  
  15.   
  16.     <!-- 将上面两个注解和并 -->  
  17.     <mvc:annotation-driven />  
  18.   
  19.       
  20.     <!--freemarker页面解析器 -->  
  21.     <bean id="viewResolver"  
  22.         class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
  23.         <property name="suffix" value=".ftl"></property>  
  24.         <property name="contentType" value="text/html;charset=UTF-8" />  
  25. <!--         <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> -->  
  26.         <!-- 将Spring的FreeMarkerView改成我们扩展的View -->  
  27.         <property name="viewClass" value="gd.hz.ExFreeMarkerView" />  
  28.         <property name="exposeRequestAttributes" value="true" />  
  29.         <property name="exposeSessionAttributes" value="true" />  
  30.         <property name="exposeSpringMacroHelpers" value="true" />  
  31.     </bean>  
  32.    
  33.     <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />  
  34.    
  35.     <!--配置Freemarker -->  
  36.     <bean id="freemarkerConfigurer"  
  37.         class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
  38.         <!-- 模版页面存放的位置 -->  
  39.          <property name="templateLoaderPath" value="/ftl/"></property>  
  40.         <property name="freemarkerVariables">  
  41.             <map>  
  42.                 <entry key="xml_escape" value-ref="fmXmlEscape" />  
  43.             </map>  
  44.         </property>  
  45.         <property name="freemarkerSettings">  
  46.             <props>  
  47.                 <prop key="template_update_delay">10</prop>  
  48.                 <prop key="defaultEncoding">UTF-8</prop>  
  49.             </props>  
  50.         </property>  
  51.     </bean>  
  52.       
  53.     <!-- 下面要声明在模版后面 -->  
  54.     <bean  
  55.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  56.         <!-- JSP页面存放的位置 -->  
  57.         <property name="prefix" value="/jsp/" />  
  58.         <property name="suffix" value=".jsp" />  
  59.     </bean>   
  60. </beans>  

 这里页面额外说明的是,如果我们想一个网站有使用freeMarker和jsp时,也可以在配置文件中声明如:

Xml代码  收藏代码
  1. <bean  
  2.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  3.         <!-- JSP页面存放的位置 -->  
  4.         <property name="prefix" value="/jsp/" />  
  5.         <property name="suffix" value=".jsp" />  
  6.     </bean>   

 这句话要声明在使用freeMarker配置下面,这样当处sping 找不到相关页面模板时就会找相关名称的jsp页面.另外还需要声明使用我们扩展的ExFreeMarkerView.

 

第四步:创建测试页:

模板页:

Html代码  收藏代码
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  2. <html>  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  5. <title></title>  
  6. </head>  
  7. <body>  
  8.     ${content}  
  9. </body>  
  10. </html>  

JSP页面:

Java代码  收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <title></title>  
  8. </head>  
  9. <body>  
  10. 我是从jsp过来的.${content }  
  11. </body>  
  12. </html  

  

 

 

 

第五步:Controller

Java代码  收藏代码
  1. package gd.hz.controller;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5. import org.springframework.web.servlet.ModelAndView;  
  6.   
  7. @Controller("indexController")  
  8. public class IndexController {  
  9.   
  10.     @RequestMapping("index")  
  11.     public ModelAndView index(){  
  12.         ModelAndView modelAndView = new ModelAndView("index");  
  13.         modelAndView.addObject("content""网站标题");  
  14.           
  15.         //当设置false时不生成静态页面  
  16.         modelAndView.addObject("STATIC_HTML"false);  
  17.           
  18.         return modelAndView;  
  19.     }  
  20.       
  21.     @RequestMapping("html/index")  
  22.     public ModelAndView htmlIndex(){  
  23.         ModelAndView modelAndView = new ModelAndView("index");  
  24.         //默认是生成静态页面的  
  25.         modelAndView.addObject("content""网站标题");  
  26.         return modelAndView;  
  27.     }  
  28.       
  29.     //jsp测试  
  30.     @RequestMapping("jsp/index")  
  31.     public ModelAndView jspindex(){  
  32.         ModelAndView modelAndView = new ModelAndView("test");  
  33.         modelAndView.addObject("content""网站标题");  
  34.         return modelAndView;  
  35.     }  
  36. }  

 首先看一下第一个请求,这里我们声明STATIC_HTML=false,不生成静态页面.第二个请求,我们生成的静态页面,根据ExFreeMarkerView中的定义,会跳转到静态页面.

第三个请求,因为没有test.ftl,这样spring 会去找test.jsp页面,所发请求会到test.jsp.

 

经过上面的三种方法,我们使用在进行大型网站开发时,可以灵活运用,可以在页面的某些数据变化少的地方进行部分页面静态化.也可以根据需求,只请求JSP页面.

0 1
原创粉丝点击