FreeMarker 使用入门及静态页面的生成


在编写静态页面的时候,往往 header,nav, footer,side 部分是通用的。 最重要的是:此时,如果你是根据 Fireworks 或者 Photoshop 来进行编写,那么文案、链接等很多东西都是不确定,这样就会导致频繁的修改。如果页面一多,且修改的是通用部分。那么你麻烦了,至于啥麻烦,你懂的!



为了避免这样的情况发生,你可以使用一些模版引擎来解决这样的问题。在此,我就给大家介绍一下我所使用的模版引擎吧。



模版引擎:FreeMarker



开发工具:NetBeans



步骤:



1. 新建一个 Maven Web Application



2. 找到 pom.xml 添加依赖和构建插件


<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.22</version>
<configuration>
<connectors>
<connector implementation=”org.mortbay.jetty.nio.SelectChannelConnector”>
<port>8084</port>
</connector>
</connectors>
<stopKey>stop</stopKey>
<stopPort>4501</stopPort>
<webAppConfig>
<contextPath>/</contextPath>
</webAppConfig>
<scanIntervalSeconds>1</scanIntervalSeconds>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>6.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

3. 修改 web.xml,配置 FreeMarker 和 请求解析的 servlet
<?xml version=”1.0” encoding=”UTF-8”?>
<web-app id=”WebApp_ID” version=”2.4” xmlns=”http://java.sun.com/xml/ns/j2ee“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt;
<display-name>FreeMarkerTest</display-name>
<welcome-file-list>
<welcome-file>/index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
<!– 下面配置FreeMarker的ftl文件位置 –>
<init-param>
<param-name>TemplatePath</param-name>
<param-value>/</param-value>
</init-param>
<!– 是否和服务器(tomcat)一起启动,0为不,1为是 –>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>.ftl</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RequestServlet</servlet-name>
<servlet-class>org.b3log.RequestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestServlet</servlet-name>
<url-pattern>
.html</url-pattern>
</servlet-mapping>
</web-app>

4. 编写解析类。通过 URL 访问时,就会对所访问的页面相应的生成一个静态页面。:由于 CSS 和 JS 的引入,在路径上需要保持一致,使得所生成的静态页面也能正确访问到 CSS 和 JS。
package org.b3log;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/* 页面渲染 & 静态页面生成.
@author <a href=”http://vanessa.b3log.org">Liyuan Li</a>
@version 1.0.0.1, Jan 30, 2014 /
public class RequestServlet extends HttpServlet {

public RequestServlet() {
super();
}

//负责管理FreeMarker模板的Configuration实例
private Configuration cfg = null;

@Override
public void init() throws ServletException {
//创建一个FreeMarker实例
cfg = new Configuration();
//指定FreeMarker模板文件的位置
cfg.setServletContextForTemplateLoading(getServletContext(), “/WEB-INF/view”);
cfg.setDefaultEncoding(“UTF-8”);
}

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//建立数据模型
Map root = new HashMap();

// 模版处理
String urlPath = request.getServletPath();
Template t = cfg.getTemplate(urlPath.replace(“.html”, “.ftl”));
t.setEncoding(“UTF-8”);
response.setContentType(“text/html; charset=UTF-8”);
Writer writer = response.getWriter();
try {
t.process(root, writer);
} catch (TemplateException ex) {
Logger.getLogger(RequestServlet.class.getName()).log(Level.SEVERE, null, ex);
}

// 静态页面生成
String genPath = “E:/working/b3log/src/main/webapp” + urlPath.replace(“\“, “/“);
File flie = new File(genPath);
File dir = new File(genPath.replaceAll(“(/\w*.html)”, “”));
if (!flie.exists()) {
dir.mkdirs();
flie.createNewFile();
}

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(genPath), “UTF-8”);
try {
t.process(root, out);
} catch (TemplateException ex) {
Logger.getLogger(RequestServlet.class.getName()).log(Level.SEVERE, null, ex);
}
out.flush();
out.close();
}

@Override
public void destroy() {
super.destroy();
}
}

5. 为了方便运行,在 Project Files 下添加 nbactions.xml,这样右键 Custom 中就可以选择 jetty-run 或者 jetty-debug 来运行程序了。
<?xml version=”1.0” encoding=”UTF-8”?>
<actions>
<action>
<actionName>CUSTOM-jetty-run</actionName>
<displayName>jetty-run</displayName>
<goals>
<goal>jetty:run</goal>
</goals>
</action>
<action>
<actionName>CUSTOM-jetty-debug</actionName>
<displayName>jetty-debug</displayName>
<goals>
<goal>jetty:run</goal>
</goals>
<properties>
<jpda.listen>maven</jpda.listen>
</properties>
</action>
</actions>

6. 开始编写 FreeMarker 页面吧
<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8” />
<title>B3log.org</title>
<#include “../common/meta.ftl”>
</head>
<body>
<#include “../common/header.ftl”>
<div>
hello, FreeMarker & static page!
</div>
<#include “../common/footer.ftl”>
</body>
</html>



 最后附上项目目录结构