├── .classpath
├── .gitignore
├── .project
├── .settings
├── .jsdtscope
├── org.eclipse.jdt.core.prefs
├── org.eclipse.m2e.core.prefs
├── org.eclipse.wst.common.component
├── org.eclipse.wst.common.project.facet.core.xml
├── org.eclipse.wst.jsdt.ui.superType.container
├── org.eclipse.wst.jsdt.ui.superType.name
└── org.eclipse.wst.validation.prefs
├── README.md
├── pom.xml
└── src
└── main
├── java
├── com
│ └── zhangguo
│ │ └── springmvc71
│ │ ├── Services
│ │ └── ArticleService.java
│ │ ├── actions
│ │ └── News.java
│ │ ├── demo
│ │ └── HelloWorld.java
│ │ └── entities
│ │ └── Article.java
└── templates
│ ├── news.ftl
│ ├── newsList.ftl
│ └── product.ftl
└── webapp
├── META-INF
└── MANIFEST.MF
├── WEB-INF
└── web.xml
└── index.jsp
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SpringMVC71
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.wst.jsdt.core.javascriptValidator
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.wst.common.project.facet.core.builder
20 |
21 |
22 |
23 |
24 | org.eclipse.m2e.core.maven2Builder
25 |
26 |
27 |
28 |
29 | org.eclipse.wst.validation.validationbuilder
30 |
31 |
32 |
33 |
34 |
35 | org.eclipse.jem.workbench.JavaEMFNature
36 | org.eclipse.wst.common.modulecore.ModuleCoreNature
37 | org.eclipse.jdt.core.javanature
38 | org.eclipse.m2e.core.maven2Nature
39 | org.eclipse.wst.common.project.facet.core.nature
40 | org.eclipse.wst.jsdt.core.jsNature
41 |
42 |
43 |
--------------------------------------------------------------------------------
/.settings/.jsdtscope:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
4 | org.eclipse.jdt.core.compiler.compliance=1.7
5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
8 | org.eclipse.jdt.core.compiler.source=1.7
9 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.common.component:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.common.project.facet.core.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.jsdt.ui.superType.container:
--------------------------------------------------------------------------------
1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.jsdt.ui.superType.name:
--------------------------------------------------------------------------------
1 | Window
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.validation.prefs:
--------------------------------------------------------------------------------
1 | disabled=06target
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Spring_MVC_071
2 |
3 |
4 | Spring MVC 学习总结(七)——FreeMarker模板引擎与动态页面静态化
5 |
6 |
7 |
8 | http://www.cnblogs.com/best/p/5681511.html
9 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.zhangguo
5 | SpringMVC71
6 | 0.0.1-SNAPSHOT
7 | war
8 |
9 |
10 |
11 | org.freemarker
12 | freemarker-gae
13 | 2.3.25-incubating
14 |
15 |
16 |
17 | javax.servlet
18 | javax.servlet-api
19 | 3.0.1
20 | provided
21 |
22 |
23 |
24 | javax.servlet.jsp
25 | jsp-api
26 | 2.1
27 | provided
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/main/java/com/zhangguo/springmvc71/Services/ArticleService.java:
--------------------------------------------------------------------------------
1 | package com.zhangguo.springmvc71.Services;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import com.zhangguo.springmvc71.entities.Article;
6 |
7 | /**
8 | * 文章业务类(模拟)
9 | *
10 | */
11 | public class ArticleService {
12 | private static List articles;
13 |
14 | static {
15 | articles = new ArrayList();
16 | articles.add(new Article(20160701, "不明真相的美国人被UFO惊呆了 其实是长征7号","据美国《洛杉矶时报》报道,当地时间周三晚(北京时间周四),在美国中西部的犹他州、内华达州、加利福利亚州,数千人被划过夜空的神秘火球吓到"));
17 | articles.add(new Article(20160702, "法国巴黎圣母院为教堂恐袭案遇害神父举行大弥撒", "而据美国战略司令部证实,其实这是中国长征七号火箭重新进入大气层,刚好经过加利福利亚附近。"));
18 | articles.add(new Article(20160703, "日东京知事候选人小池百合子回击石原:浓妆可以", "然而昨晚的美国人民可不明真相,有些人甚至怀疑这些火球是飞机解体,还有些人猜测是流星雨。"));
19 | articles.add(new Article(20160704, "日资慰安妇基金在首尔成立 韩国示威者闯入抗议","美国战略司令部发言人表示,到目前为止还没有任何受损报告,他说类似物体通常在大气中就会消失,这也解释了为何出现一道道光痕,这一切都并未造成什么威胁。"));
20 | articles.add(new Article(20160705, "中日关系正处十字路口日应寻求减少与华冲突","中国长征七号火箭6月25日在海南文昌航天发射中心首次发射,并成功升空进入轨道。有学者指出长征七号第二级火箭一直在地球低轨运行,一个月后重新进入大气层。"));
21 | }
22 |
23 | /**
24 | * 所有的文章
25 | */
26 | public List getArticles() {
27 | return articles;
28 | }
29 |
30 | /*
31 | * 获得文章通过文章编号
32 | */
33 | public Article getArticle(int id) {
34 | for (Article article : articles) {
35 | if (article.getId() == id) {
36 | return article;
37 | }
38 | }
39 | return null;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/zhangguo/springmvc71/actions/News.java:
--------------------------------------------------------------------------------
1 | package com.zhangguo.springmvc71.actions;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.OutputStreamWriter;
7 | import java.io.Writer;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 | import javax.servlet.ServletException;
12 | import javax.servlet.annotation.WebServlet;
13 | import javax.servlet.http.HttpServlet;
14 | import javax.servlet.http.HttpServletRequest;
15 | import javax.servlet.http.HttpServletResponse;
16 | import com.zhangguo.springmvc71.Services.ArticleService;
17 | import com.zhangguo.springmvc71.entities.Article;
18 | import freemarker.template.Configuration;
19 | import freemarker.template.Template;
20 | import freemarker.template.TemplateException;
21 |
22 | /**
23 | *新闻列表
24 | */
25 | @WebServlet("/News")
26 | public class News extends HttpServlet {
27 | private static final long serialVersionUID = 1L;
28 |
29 | ArticleService articleService=new ArticleService();
30 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
31 | //设置编码格式与MIME类型
32 | response.setContentType("text/html; charset=UTF-8");
33 |
34 | //首页新闻列表路径
35 | String indexPath=request.getServletContext().getRealPath("/index.html");
36 |
37 | //文件是否存在
38 | File file=new File(indexPath);
39 | if(!file.exists()){
40 | //如果新闻列表不存在,生成新闻列表
41 |
42 | //创建一个freemarker.template.Configuration实例,它是存储 FreeMarker 应用级设置的核心部分
43 | //指定版本号
44 | Configuration cfg=new Configuration(Configuration.VERSION_2_3_22);
45 | //获得模板文件路径
46 | String templatePath=this.getClass().getClassLoader().getResource("/templates").getPath();
47 | //设置模板目录
48 | cfg.setDirectoryForTemplateLoading(new File(templatePath));
49 | //设置默认编码格式
50 | cfg.setDefaultEncoding("UTF-8");
51 |
52 | //数据
53 | Map articleData = new HashMap<>();
54 | List articles=articleService.getArticles();
55 | articleData.put("articles", articles);
56 |
57 | //从设置的目录中获得模板
58 | Template template = cfg.getTemplate("newsList.ftl");
59 |
60 | //合并模板和数据模型
61 | try {
62 | //将数据与模板渲染的结果写入文件中
63 | Writer writer=new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
64 | template.process(articleData, writer);
65 | writer.flush();
66 |
67 | articleData.clear();
68 | template = cfg.getTemplate("news.ftl");
69 | //生成单个新闻文件
70 | for (Article article : articles) {
71 | articleData.put("article", article);
72 | //单个新闻文件
73 | file=new File(request.getServletContext().getRealPath("/news/"+article.getId()+".html"));
74 | //文件输出流写入器
75 | writer=new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
76 | //将模板+数据生成的结果写入文件中,得到一个静态文件
77 | template.process(articleData, writer);
78 | writer.flush();
79 | }
80 | writer.close();
81 | } catch (TemplateException e) {
82 | e.printStackTrace();
83 | }
84 | }
85 | //如果新闻单页下存在,生成新闻单页
86 | request.getRequestDispatcher("index.html").forward(request, response);
87 | }
88 |
89 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
90 | doGet(request, response);
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/com/zhangguo/springmvc71/demo/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package com.zhangguo.springmvc71.demo;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.OutputStreamWriter;
6 | import java.io.Writer;
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | import freemarker.template.Configuration;
11 | import freemarker.template.Template;
12 |
13 | public class HelloWorld {
14 |
15 | public static void main(String[] args) throws Exception {
16 |
17 | //创建一个freemarker.template.Configuration实例,它是存储 FreeMarker 应用级设置的核心部分
18 | //指定版本号
19 | Configuration cfg=new Configuration(Configuration.VERSION_2_3_22);
20 | //设置模板目录
21 | cfg.setDirectoryForTemplateLoading(new File("src/main/java/templates"));
22 | //设置默认编码格式
23 | cfg.setDefaultEncoding("UTF-8");
24 |
25 | //数据
26 | Map product = new HashMap<>();
27 | product.put("name", "Huwei P8");
28 | product.put("price", "3985.7");
29 | product.put("users", new String[]{"Tom","Jack","Rose"});
30 | product.put("book","struts2,freemarker");
31 |
32 | //从设置的目录中获得模板
33 | Template temp = cfg.getTemplate("product.ftl");
34 |
35 | //合并模板和数据模型
36 | Writer out = new OutputStreamWriter(System.out);
37 | temp.process(product, out);
38 |
39 | //关闭
40 | out.flush();
41 | out.close();
42 |
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/zhangguo/springmvc71/entities/Article.java:
--------------------------------------------------------------------------------
1 | package com.zhangguo.springmvc71.entities;
2 |
3 | /**
4 | * 文章
5 | *
6 | */
7 | public class Article {
8 | /*
9 | * 编号
10 | */
11 | private int id;
12 | /*
13 | * 标题
14 | */
15 | private String title;
16 | /*
17 | * 内容
18 | */
19 | private String content;
20 |
21 | public Article() {
22 | }
23 |
24 | public Article(int id, String title, String content) {
25 | super();
26 | this.id = id;
27 | this.title = title;
28 | this.content = content;
29 | }
30 |
31 | public int getId() {
32 | return id;
33 | }
34 |
35 | public void setId(int id) {
36 | this.id = id;
37 | }
38 |
39 | public String getTitle() {
40 | return title;
41 | }
42 |
43 | public void setTitle(String title) {
44 | this.title = title;
45 | }
46 |
47 | public String getContent() {
48 | return content;
49 | }
50 |
51 | public void setContent(String content) {
52 | this.content = content;
53 | }
54 |
55 | @Override
56 | public String toString() {
57 | return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/templates/news.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ${article.title}
6 |
7 |
8 |
9 |
${article.title}
10 |
11 | ${article.content}
12 |
13 |
14 |
21 |
22 |
--------------------------------------------------------------------------------
/src/main/java/templates/newsList.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 新闻焦点
6 |
7 |
8 |
9 |
新闻焦点
10 | <#setting number_format="#">
11 |
12 | <#list articles as article>
13 | -
14 | ${article.title}
15 |
16 | #list>
17 |
18 |
19 |
34 |
35 |
--------------------------------------------------------------------------------
/src/main/java/templates/product.ftl:
--------------------------------------------------------------------------------
1 | ----------产品详细----------
2 | 产品名称:${name}
3 | 产品价格:${price}
4 | 设计作者:<#list users as user> ${user} #list>
5 | ------------------------------
6 |
7 | <#assign test="Tom & Jerry">
8 | ${test?html}
9 | ${test?upper_case?html}
10 |
11 | ${tom!"tom is missed"}
12 | <#if !jack??>jack is missed#if>
13 |
14 | <#assign age=23>
15 | <#if (age>60)>老年人
16 | <#elseif (age>40)>中年人
17 | <#elseif (age>20)>青年人
18 | <#else> 少年人
19 | #if>
20 |
21 |
22 | <#assign level=1>
23 | <#switch level>
24 | <#case 1>A级<#break>
25 | <#case 2>B级<#break>
26 | <#case 3>C级<#break>
27 | <#default>未知级别
28 | #switch>
29 |
30 | <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as week>
31 | ${week_index + 1}.${week}<#if week_has_next>,#if>
32 | <#if week="星期四"><#break>#if>
33 | #list>
34 |
35 | <#assign weeks>
36 | <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
37 | ${n}
38 | #list>
39 | #assign>
40 | ${weeks}
41 |
42 | <#macro book> //定义一个自定义指令
43 | j2ee
44 | #macro>
45 | <@book /> //使用刚才定义的指令
46 |
47 | <#macro book booklist> //定义一个自定义指令booklist是参数
48 | <#list booklist as book>
49 | ${book}
50 | #list>
51 | #macro>
52 | <@book booklist=["spring","j2ee"] /> //使用刚刚定义的指令
53 |
54 |
55 | <#macro book>
56 | <#nested 1>
57 | <#nested 2>
58 | <#nested 3>
59 | #macro>
60 | <@book ;index> ${index} .图书@book>
61 |
62 |
63 | <#macro repeat count>
64 | <#list 1..count as x>
65 | <#nested x, x/2, x==count>
66 | #list>
67 | #macro>
68 |
69 | <@repeat count=4 ;c,halfc,last>
70 | ${c}. ${halfc}<#if last> Last! #if>
71 | @repeat>
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/src/main/webapp/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | index.html
8 | index.jsp
9 |
10 |
--------------------------------------------------------------------------------
/src/main/webapp/index.jsp:
--------------------------------------------------------------------------------
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2 |
--------------------------------------------------------------------------------