超级通道 :Spring MVC代码实例系列-绪论
本章主要记录Spring MVC配置Freemarker实现页面静态化的简单实例,涉及到的技术有:
##1.程序目录
src
\---main
\---java
| \---pers
| \---hanchao
| \---hespringmvc
| \---freemarker
| \---News.java
| \---FreeMarkerController.java
| \---NewsController.java
\---webapp
\---freemarker
| \---index.jsp
| \---main.ftl
| \---news.ftl
\---html
| \---news
\---WEB-INF
| \---spring-mvc-servlet.xml
| \---web.xml
\---index.jsp
##2.pom.xml
<freemarker.version>2.3.23freemarker.version>
<dependency>
<groupId>org.freemarkergroupId>
<artifactId>freemarkerartifactId>
<version>${freemarker.version}version>
dependency>
##3.spring-mvc-servlet.xml
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/freemarker/"/>
<property name="defaultEncoding" value="UTF-8"/>
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">3600prop>
<prop key="locale">zh_CNprop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ssprop>
<prop key="date_format">yyyy-MM-ddprop>
<prop key="number_format">#.##prop>
props>
property>
bean>
##4.News.java
package pers.hanchao.hespringmvc.freemarker;
/**
* 新闻
* @author hanchao 2018/1/21 13:31
**/
public class News {
/** 新闻编号 */
private Integer id;
/** 新闻标题 */
private String title;
/** 新闻内容 */
private String content;
public News() {}
public News(Integer id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
//toString
//settr and getter
}
##5.FreeMarkerController.java
package pers.hanchao.hespringmvc.freemarker;
import freemarker.template.Template;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import pers.hanchao.hespringmvc.log4j.App;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Map;
/**
* 提供创建HTML文件的方法的父类
* @author hanchao 2018/1/21 18:12
**/
public class FreeMarkerController {
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
private String charset = "UTF-8";
private static final Logger LOGGER = Logger.getLogger(App.class);
/** 过期时间单位 毫秒*/
private Long expireTime = 86400000L;
/**
*
* ftlFileName 模板文件名
* model 数据模型
* htmlFilePath 保存的html文件全路径
* @author hanchao 2018/1/21 16:19
**/
public String creatHtml(HttpServletRequest request, String ftlFileName, Map model, String htmlMappingPath) throws Exception{
//获取目标Html文件的绝对路径
String htmlFilePath = request.getServletContext().getRealPath("/") + htmlMappingPath.replace("/",File.separator) + ".html";
LOGGER.debug("htmlFilePath:" + htmlFilePath);
//如果文件不存在 或者 文件存在且已经超过了过期时间,则重新生成
//或者说如果文件存在且还未超过过期时间,则什么也不做
File file = new File(htmlFilePath);
if (file.exists()){
Long interval = System.currentTimeMillis() - file.lastModified() - this.expireTime;
LOGGER.debug("System.currentTimeMillis():" + System.currentTimeMillis());
LOGGER.debug("file.lastModified():" + file.lastModified());
LOGGER.debug("this.expireTime:" + this.expireTime);
LOGGER.debug("interval:" + interval);
if (interval < 0){
return htmlMappingPath;
}else {//如果文件超过了过期时间,则删除文件
file.delete();
}
}
//读取模板文件,填充模型数据,形成html字符串
StringWriter sw = new StringWriter();
Template template = freeMarkerConfigurer.getConfiguration().getTemplate(ftlFileName + ".ftl");
template.process(model,sw);
sw.close();
String htmlStr = sw.toString();
//将html字符串写到html文件中
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file,true);
outputStream.write(htmlStr.getBytes(charset));
outputStream.close();
LOGGER.info("生成HTML文件:" + htmlFilePath);
return htmlMappingPath;
}
}
##6.NewsController.java
package pers.hanchao.hespringmvc.freemarker;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* freemarker页面的静态化的简单实例
* @author hanchao 2018/1/21 18:12
**/
@Controller
@RequestMapping("freemarker")
public class NewsController extends FreeMarkerController {
/**
* 通过@ModelAttribute造数
* @author hanchao 2018/1/21 13:40
**/
@ModelAttribute
public void init(Model model){
News[] newsArray = new News[10];
Integer id = 1000000;
String title = "新闻标题00";
String content = "新闻内容00";
for (int i = 0; i < 10; i++) {
newsArray[i] = new News(id + i,title + i,content + i);
}
model.addAttribute("newsArray",newsArray);
}
/**
* 获取新闻列表
* @author hanchao 2018/1/21 13:35
**/
@GetMapping("/news/")
public String getAllNews(HttpServletRequest request,@ModelAttribute("newsArray") News[] newsArray, Model model) throws Exception {
Map newsMap = new HashMap<String ,News[]>();
newsMap.put("newsArray",newsArray);
return this.creatHtml(request,"main",newsMap,"/html/news/main");
}
/**
* 获取新闻详情
* @author hanchao 2018/1/21 13:49
**/
@GetMapping("/news/{id}")
public String getNews(HttpServletRequest request,@PathVariable Integer id,@ModelAttribute("newsArray") News[] newsArray, Model model) throws Exception {
Map newsMap = new HashMap<String ,News[]>();
newsMap.put("news",newsArray[id - 1000000]);
return this.creatHtml(request,"news",newsMap,"/html/news/" + id);
}
/**
*
* @author hanchao 2018/1/21 18:17
**/
@GetMapping("/ftl")
public String getFtl(Model model){
model.addAttribute("title","ftl测试");
model.addAttribute("content","这是一个ftl测试");
model.addAttribute("CREATE_HTML", true);
return "/freemarker/demo";
}
}
##7.main.ftl
<html>
<head>
<title>新闻首页title>
head>
<body>
<#list newsArray as news>
<li>
<a href="/freemarker/news/${news.id}">${news.title}a>
li>
#list>
body>
html>
##8.news.ftl
<html>
<head>
<title>新闻详情title>
head>
<body>
<h3>${news.title}h3>
<p>${news.title}p>
body>
html>