Java springmvc+freemarker生成HTML模板页

freemarker: 实现 数据+模板=输出

其利用ftl模板文件,生成html静态文件。起初认为他生成html后就一直不改变了,这里就一直困惑,既然html静态化了,那么其他人访问时数据改变了,这个html文件不就不能用了吗。最后才发现其每次访问都会重新生成html,然后再访问这个html。

要解决高并发问题,我们只需要把动态网页做成静态网页就可以了,但是问题出来了,如果将所有页面都做成静态页面显然是不切实际的。有什么办法能让我们的网站即能有动态网页的交互性,又有静态网页的加载速度呢?FreeMarker便能实现这样的需求:实现动态网页静态化。

**

总结:freemarker应该对一些实时性要求不太高的页面做静态化处理,且不会每次访问都生成一次html文件。在请求时会判断该html存不存在,然后再做是否生成判断。该结论有待实际项目中验证

freemarker.properties

classic_compatible=true              
##如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
whitespace_stripping=true          
##去掉多余的空格,非常有用
##模版更新事件,设置为1秒,正式环境设置为3600秒
#template_update_delay=3600
template_update_delay=1        
##模版更新时间,这里配置是1秒更新一次,正式环境,模版不会改变,可以将这个值设很大,提高效率.就是被这个参数害死了.老是不更新.
locale=zh_CN           
 ##中国
default_encoding=utf-8   
##编码utf8
url_escaping_charset=utf-8  
##url编码utf8
date_format=yyyy-MM-dd   
##显示日期格式
time_format=HH:mm:Ss       
##显示时间格式
datetime_format=yyyy-MM-dd  
##显示日期格式
number_format=\#0.\#\#\#\#\#  
##数字显示格式hi.
#template_update_delay=1
datetime_format=yyyy-MM-dd HH:mm:ss
date_format=yyyy-MM-dd
time_format=HH:mm:ss
number_format=0.######;
boolean_format=true,false
##auto_import="/common/index.ftl" as ui
whitespace_stripping=true
default_encoding=UTF-8
tag_syntax=auto_detect 
##设置标签的类型
url_escaping_charset=UTF-8

application-freemarker.xml


<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd   
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd   
                        http://www.springframework.org/schema/tx    
                        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
                        http://www.springframework.org/schema/aop 
                        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> 
<!-- 配置Freemarker属性文件路径 -->
<bean id="freemarkerConfiguration" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="order" value="3" />
    <property name="location">
			<value>/WEB-INF/config/freemarker.properties</value>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true" /> 
</bean>
<!-- 配置freeMarker模板加载地址 -->
<bean  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <!-- 视图解析器会在/WEB-INF/ftl/路径下扫描视图文件 -->
    <property name="templateLoaderPath" value="/templates/ftl/" />
    <property name="freemarkerSettings">
	   <props>
	    <prop key="template_update_delay">0</prop>
	    <prop key="default_encoding">${default_encoding}</prop>
	    <prop key="datetime_format">${datetime_format}</prop>  
	    <prop key="locale">${locale}</prop>
	   </props>
	</property>
   <!--  <property name="freemarkerVariables">
        <map>
            <entry key="xml_escape" value-ref="fmXmlEscape" />
        </map>
    </property> -->
</bean>
<!-- escapeXml方法过滤特殊字符 -->
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />
<!-- 配置freeMarker视图解析器 -->
<bean id="freemarkerConfig"        class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <!-- <property name="viewClass"        value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> -->
    <property name="viewClass"        value="com.general.common.freemarker.MyFreeMarkerView" />
    <property name="order" value="0"></property>
    <property name="cache" value="false"></property>
    <property name="suffix" value=".ftl" />  
    <property name="contentType" value="text/html;charset=UTF-8" />  
    <!-- 此变量值为pageContext.request, 页面使用方法:rc.contextPath -->  
    <property name="requestContextAttribute" value="rc" />  
    
</bean>
</beans>                    

重写了视图解析器vieclass

package com.controller.freemarker;

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;    */ 
            String htmlPath = basePath +"templates"+ 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);*/
            request.getRequestDispatcher("/templates/"+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";*/
        requestURI = requestURI+ ".html";
        return requestURI;
     }
}

@RequestMapping("/map")  
    public ModelAndView map1(HttpServletRequest request, HttpServletResponse response) {  
        List<Xiaoqu> xiaoqulist = new ArrayList<Xiaoqu>(); 
        double [] longitude = {117.296979,116.8198,119.011435,115.813411};
        double [] latitude = {31.839387,31.375842,29.860429,32.300805};
	    String [] name = {"\'名城\'","\'尚贤居\'","\'复兴家园\'","\'永和村\'"};
	    String [] count = {"103","203","502","401"};
		try {
	        for(int i=0;i<4;i++){
	        	Xiaoqu xq = new Xiaoqu();
 	        	xq.setLongitude(longitude[i]);
 	        	xq.setLatitude(latitude[i]);
 	        	xq.setCount(count[i]);
	        	xq.setName(name[i]);
	            xiaoqulist.add(xq);
	        }
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
          
        return new ModelAndView("map", "xiaoqulist", xiaoqulist);  
    } 
@RequestMapping("/map2")  
    public ModelAndView map2(HttpServletRequest request, HttpServletResponse response) {  
        ModelAndView mv = new ModelAndView();
        //在这里可以控制不生成静态htm  
        mv.addObject("CREATE_HTML", false);  
        mv.setViewName("index");
        return mv;  
    } 

注:之前生成html 文件一直访问不到,因为spring 对静态文件做了拦截

web.xml添加:
<!-- freemarker 生成的html静态文件  -->
  <servlet-mapping >
             <servlet-name >default</servlet-name >
             <url-pattern >*.html</url-pattern>
   </servlet-mapping >

转载于:https://my.oschina.net/maoguangdong/blog/878830

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值