页面静态化基本实现是指对一些网页内容更新较少的情况下,可以在用户第一次发送请求时动态获取页面内容,并同时生成html的静态页面,再以后的访问中直接对静态页面进行访问,可以大大加快页面的访问速度,可以通过freemarker与UrlRewriteFilter一起作用实现。
UrlRewriteFilter
UrlRewriteFilter是一种url重写的拦截器,可以接受你的请求url,并转为另一个url,需要在web.xml配置如下拦截器,但原本的拦截器在所有情况下都会进行url重写,不符合要求,需要对默认拦截器进行复写
<filter>
<filter-name>UrlRewriteFilterfilter-name>
<filter-class>com.baizhi.filter.CostomFilterfilter-class>
filter>
<filter-mapping>
<filter-name>UrlRewriteFilterfilter-name>
<url-pattern>/*url-pattern>
<dispatcher>REQUESTdispatcher>
<dispatcher>FORWARDdispatcher>
filter-mapping>
想要实现url重写需要些如下配置文件,如下/gameview/game_([0-9]+).html$
请求会被转为/back/game?id=$1&path=$0
进入Controller
<urlrewrite>
<rule match-type="regex">
<note>
note>
<from>/gameview/game_([0-9]+).html$from>
<to type="forward">/back/game?id=$1&path=$0to>
rule>
urlrewrite>
对UrlRewriteFilter的重写如下
public class CostomFilter extends UrlRewriteFilter{
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 当静态文件存在时调用本类的doFilter通过请求直接访问存在的html静态页面
if(isStatic(request)){
if(isExist(request)){
chain.doFilter(request, response);
}else {
// 当静态文件不存在时调用父类dofilter进入url重写
super.doFilter(request, response, chain);
}
}else {
// 当静态文件不存在时调用父类dofilter进入url重写
super.doFilter(request, response, chain);
}
}
public boolean isStatic(ServletRequest rq){
//将ServletRequest强转为HttpServletRequest
HttpServletRequest req=(HttpServletRequest) rq;
//获得项目名+请求的正则表达式
String patternStr=req.getContextPath()+"/gameview/game_([0-9]+).html$";
Pattern pattern=Pattern.compile(patternStr);
//获得请求URI路径,与正则表达式进行匹配,如果成功匹配返回true
String uri=req.getRequestURI();
Matcher matcher = pattern.matcher(uri);
boolean matches = matcher.matches();
//判断是否为静态化请求,如果不是不需要走Filter
return matches;
}
public boolean isExist(ServletRequest rq){
HttpServletRequest req=(HttpServletRequest) rq;
//获得文件路径
String realPath=req.getSession().getServletContext().getRealPath("").replace("\\", "/");
realPath=realPath.replace(req.getContextPath(), "");
String filePath=realPath+req.getRequestURI();
File file=new File(filePath);
//判断静态文件是否存在
if(!file.exists()){
return false;
}else{
//给tomcat足够的反应时间
if((new Date().getTime()-file.lastModified())<5000){
return false;
}
}
return true;
}
}
静态页面不存在时,请求放行至Controller
@Controller
@RequestMapping("/back")
public class UrlController {
@RequestMapping("/game")
public String test(HttpServletRequest request,ModelMap map,String id,String path) throws Exception{
//将信息存入map以备生成静态页面
map.put("game", new Game(1,"speedrunner",new Date()));
//获得请求路径,也就是生成的静态页面应该存入的路径
String realPath = request.getSession().getServletContext().getRealPath(path);
File file =new File(realPath);
//获得模板目录
String tempPath=request.getSession().getServletContext().getRealPath("/template");
//判断静态页面是否存在,不存在则生成静态页面
if(!file.exists()){
//参数分别为(模板目录,map,生成静态文件的输出流,模板文件)
HtmlUtils.genHtml(tempPath, map, new FileOutputStream(realPath), "game.html");
}
return "game/gameDetail";
}
}
FreeMarker
freemarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。
freemarker生成静态页面的工具类代码如下
public class HtmlUtils {
public static void genHtml(String path,Object root,OutputStream out,String tempName){
try {
//1、创建Configuration
Configuration conf=new Configuration(Configuration.VERSION_2_3_23);
//2、设置模板路径
File file=new File(path);
conf.setDirectoryForTemplateLoading(file);
//setClassForTemplateLoading(TestFTL.class, "com/baizhi/ftl");
//3、设置模板的加载编码格式
conf.setDefaultEncoding("UTF-8");
//4、设置数字格式
conf.setNumberFormat("####");
conf.setDateFormat("yyyy年MM月dd日");
conf.setDateTimeFormat("yyyy年MM月dd日 HH时mm分ss秒");
//5、获取模板
Template template = conf.getTemplate(tempName);
//6、通过输出流获得printwriter
PrintWriter pw=new PrintWriter(new OutputStreamWriter(out, Charset.forName("utf-8")));
template.process(root, pw);
pw.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}