/** */
/**
*
* <p>
* 模板预处理类,主要在输出到模板之前做一些自定义操作
* </p>
*
* <p>
* 以下为FreemarkerServlet的具体执行顺序
* </p>
* <ul>
* <li type="i">init()</li>
* <li type="i"> | -- createConfiguration()</li>
* <li type="i"> | -- createObjectWrapper()</li>
* <li></li>
* <li type="i"><font color="gray">process(request,response)</font></li>
* <li type="i"> | -- preprocessRequest(request, response)</li>
* <li type="i"> | -- requestUrlToTemplatePath(request)</li>
* <li type="i"> | -- deduceLocale(path, request, response))</li>
* <li type="i"> | -- createModel(wrapper, servletContext, request, response)</li>
* <li type="i"> | -- | -- initializeServletContext(request, response)</li>
* <li type="i"> | -- | -- initializeSession(request, response)</li>
* <li type="i"> | -- | -- createRequestParametersHashModel(request)</li>
* <li type="i"> | -- preTemplateProcess(request, response, template, model)</li>
* <li type="i"> | -- <font color="gray">template.process(model,
* response.getWriter())</font></li>
* <li type="i"> | -- postTemplateProcess(request, response, template, model)</li>
* </ul>
*
* <p>
* 请按照对应的执行顺序进行适当覆盖
* </p>
* <p>
* 注:灰色部分为重要的中间环节, 不是可覆盖的方法
*
* </p>
*/
public class BaseServlet extends FreemarkerServlet ... {
private static final long serialVersionUID = -7091792853096097981L;
/**//*
* <p>覆盖构建配置过程, 这里可以自定义配置</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createConfiguration()
*/
@Override
protected Configuration createConfiguration() ...{
// 取得配置
Configuration config = super.createConfiguration();
// 自动引入core模板, 此模板封装了大部分公共宏
config.addAutoInclude("/template/common/core.ftl");
return config;
}
/**//*
* <p>覆盖创建模型方法, 这里可以对模型生成过程进行定制处理</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createModel(freemarker.template.ObjectWrapper,
* javax.servlet.ServletContext, javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected TemplateModel createModel(ObjectWrapper wrapper,
ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response) throws TemplateModelException ...{
// TODO: 自定义修改模型
return super.createModel(wrapper, servletContext, request, response);
}
/**//*
* <p>覆盖创建对象树方法, 主要进行模板对象树的内容</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createObjectWrapper()
*/
@Override
protected ObjectWrapper createObjectWrapper() ...{
// TODO Auto-generated method stub
return super.createObjectWrapper();
}
/**//*
* <p>覆盖构建参数Hash列表方法, 这里可以自定义请求参数列表</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createRequestParametersHashModel(javax.servlet.http.HttpServletRequest)
*/
@Override
protected HttpRequestParametersHashModel createRequestParametersHashModel(
HttpServletRequest request) ...{
return super.createRequestParametersHashModel(request);
}
/**//*
* <p>覆盖deduceLocale方法, 主要可以自定义一些本地化的内容</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#deduceLocale(java.lang.String,
* javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected Locale deduceLocale(String str, HttpServletRequest request,
HttpServletResponse response) ...{
// TODO Auto-generated method stub
return super.deduceLocale(str, request, response);
}
/**//*
* <p>覆盖Servlet上下文方法, 主要实现自定义上下文</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#initializeServletContext(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected void initializeServletContext(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException ...{
super.initializeServletContext(request, response);
}
/**//*
* <p>覆盖初始化Session方法, 主要定制Session内容</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#initializeSession(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected void initializeSession(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException ...{
super.initializeSession(request, response);
}
/**//*
* <p>覆盖输出模板方法, 这是整个周期的最后一步, 主要做一些后期处理和收尾工作</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#postTemplateProcess(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse,
* freemarker.template.Template, freemarker.template.TemplateModel)
*/
@Override
protected void postTemplateProcess(HttpServletRequest request,
HttpServletResponse response, Template template, TemplateModel data)
throws ServletException, IOException ...{
super.postTemplateProcess(request, response, template, data);
}
/**//*
* <p>覆盖请求处理方法, 主要实现在请求被处理前的自定义操作</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#preprocessRequest(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected boolean preprocessRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException ...{
// TODO: 实现自定义Request处理
return super.preprocessRequest(request, response);
}
/**//*
* <p>覆盖模板预处理方法, 主要实现模板处理前的具体自定义操作</p> <p>这里可以加转换和模板方法的处理代码,例如:</p>
* <code> SimpleHash sh = (SimpleHash) data; sh.put("upperCase", new
* UpperCaseTransform()); </code> <p>或</p> <code> SimpleHash sh =
* (SimpleHash) data; sh.put("indexOf", new IndexOfMethod()); </code>
*
* @see freemarker.ext.servlet.FreemarkerServlet#preTemplateProcess(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse,
* freemarker.template.Template, freemarker.template.TemplateModel)
*/
@Override
protected boolean preTemplateProcess(HttpServletRequest request,
HttpServletResponse response, Template template, TemplateModel data)
throws ServletException, IOException ...{
SimpleHash sh = (SimpleHash) data;
// 装载转换器
IBuilder tb = new TransformBuilder(sh);
sh = tb.getSimpleHash();
// 装载模板方法
IBuilder mb = new MethodBuilder(sh);
sh = mb.getSimpleHash();
// 装载其他上下文
IBuilder cb = new ContextBuilder(sh, request);
sh = cb.getSimpleHash();
return super.preTemplateProcess(request, response, template, sh);
}
/**//*
* <p>覆盖获得模板路径方法, 这里可以定制模板路径</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#requestUrlToTemplatePath(javax.servlet.http.HttpServletRequest)
*/
@Override
protected String requestUrlToTemplatePath(HttpServletRequest request) ...{
return super.requestUrlToTemplatePath(request);
}
}
*
* <p>
* 模板预处理类,主要在输出到模板之前做一些自定义操作
* </p>
*
* <p>
* 以下为FreemarkerServlet的具体执行顺序
* </p>
* <ul>
* <li type="i">init()</li>
* <li type="i"> | -- createConfiguration()</li>
* <li type="i"> | -- createObjectWrapper()</li>
* <li></li>
* <li type="i"><font color="gray">process(request,response)</font></li>
* <li type="i"> | -- preprocessRequest(request, response)</li>
* <li type="i"> | -- requestUrlToTemplatePath(request)</li>
* <li type="i"> | -- deduceLocale(path, request, response))</li>
* <li type="i"> | -- createModel(wrapper, servletContext, request, response)</li>
* <li type="i"> | -- | -- initializeServletContext(request, response)</li>
* <li type="i"> | -- | -- initializeSession(request, response)</li>
* <li type="i"> | -- | -- createRequestParametersHashModel(request)</li>
* <li type="i"> | -- preTemplateProcess(request, response, template, model)</li>
* <li type="i"> | -- <font color="gray">template.process(model,
* response.getWriter())</font></li>
* <li type="i"> | -- postTemplateProcess(request, response, template, model)</li>
* </ul>
*
* <p>
* 请按照对应的执行顺序进行适当覆盖
* </p>
* <p>
* 注:灰色部分为重要的中间环节, 不是可覆盖的方法
*
* </p>
*/
public class BaseServlet extends FreemarkerServlet ... {
private static final long serialVersionUID = -7091792853096097981L;
/**//*
* <p>覆盖构建配置过程, 这里可以自定义配置</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createConfiguration()
*/
@Override
protected Configuration createConfiguration() ...{
// 取得配置
Configuration config = super.createConfiguration();
// 自动引入core模板, 此模板封装了大部分公共宏
config.addAutoInclude("/template/common/core.ftl");
return config;
}
/**//*
* <p>覆盖创建模型方法, 这里可以对模型生成过程进行定制处理</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createModel(freemarker.template.ObjectWrapper,
* javax.servlet.ServletContext, javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected TemplateModel createModel(ObjectWrapper wrapper,
ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response) throws TemplateModelException ...{
// TODO: 自定义修改模型
return super.createModel(wrapper, servletContext, request, response);
}
/**//*
* <p>覆盖创建对象树方法, 主要进行模板对象树的内容</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createObjectWrapper()
*/
@Override
protected ObjectWrapper createObjectWrapper() ...{
// TODO Auto-generated method stub
return super.createObjectWrapper();
}
/**//*
* <p>覆盖构建参数Hash列表方法, 这里可以自定义请求参数列表</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#createRequestParametersHashModel(javax.servlet.http.HttpServletRequest)
*/
@Override
protected HttpRequestParametersHashModel createRequestParametersHashModel(
HttpServletRequest request) ...{
return super.createRequestParametersHashModel(request);
}
/**//*
* <p>覆盖deduceLocale方法, 主要可以自定义一些本地化的内容</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#deduceLocale(java.lang.String,
* javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected Locale deduceLocale(String str, HttpServletRequest request,
HttpServletResponse response) ...{
// TODO Auto-generated method stub
return super.deduceLocale(str, request, response);
}
/**//*
* <p>覆盖Servlet上下文方法, 主要实现自定义上下文</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#initializeServletContext(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected void initializeServletContext(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException ...{
super.initializeServletContext(request, response);
}
/**//*
* <p>覆盖初始化Session方法, 主要定制Session内容</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#initializeSession(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected void initializeSession(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException ...{
super.initializeSession(request, response);
}
/**//*
* <p>覆盖输出模板方法, 这是整个周期的最后一步, 主要做一些后期处理和收尾工作</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#postTemplateProcess(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse,
* freemarker.template.Template, freemarker.template.TemplateModel)
*/
@Override
protected void postTemplateProcess(HttpServletRequest request,
HttpServletResponse response, Template template, TemplateModel data)
throws ServletException, IOException ...{
super.postTemplateProcess(request, response, template, data);
}
/**//*
* <p>覆盖请求处理方法, 主要实现在请求被处理前的自定义操作</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#preprocessRequest(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
protected boolean preprocessRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException ...{
// TODO: 实现自定义Request处理
return super.preprocessRequest(request, response);
}
/**//*
* <p>覆盖模板预处理方法, 主要实现模板处理前的具体自定义操作</p> <p>这里可以加转换和模板方法的处理代码,例如:</p>
* <code> SimpleHash sh = (SimpleHash) data; sh.put("upperCase", new
* UpperCaseTransform()); </code> <p>或</p> <code> SimpleHash sh =
* (SimpleHash) data; sh.put("indexOf", new IndexOfMethod()); </code>
*
* @see freemarker.ext.servlet.FreemarkerServlet#preTemplateProcess(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse,
* freemarker.template.Template, freemarker.template.TemplateModel)
*/
@Override
protected boolean preTemplateProcess(HttpServletRequest request,
HttpServletResponse response, Template template, TemplateModel data)
throws ServletException, IOException ...{
SimpleHash sh = (SimpleHash) data;
// 装载转换器
IBuilder tb = new TransformBuilder(sh);
sh = tb.getSimpleHash();
// 装载模板方法
IBuilder mb = new MethodBuilder(sh);
sh = mb.getSimpleHash();
// 装载其他上下文
IBuilder cb = new ContextBuilder(sh, request);
sh = cb.getSimpleHash();
return super.preTemplateProcess(request, response, template, sh);
}
/**//*
* <p>覆盖获得模板路径方法, 这里可以定制模板路径</p>
*
* @see freemarker.ext.servlet.FreemarkerServlet#requestUrlToTemplatePath(javax.servlet.http.HttpServletRequest)
*/
@Override
protected String requestUrlToTemplatePath(HttpServletRequest request) ...{
return super.requestUrlToTemplatePath(request);
}
}
其中主要覆盖方法为:
protected Configuration createConfiguration 和 protected boolean preTemplateProcess
createConfiguration 主要作用是自定义配置,比如预先装载模板,预先添加引用等。
preTemplateProcess主要是在处理模板前期处理一些预定义内容,如:Transform, Method, 上下文等
就像代码写的那样,可以做一个接口:
public
interface
IBuilder
...
{
public SimpleHash getSimpleHash();
}
public SimpleHash getSimpleHash();
}
然后实现这个接口生成Transform, Method, 上下文等,例如Transform:
public
class
TransformBuilder
implements
IBuilder
...
{
private SimpleHash sh;
public TransformBuilder(SimpleHash sh) ...{
this.sh = sh;
}
/**//*
* 装配转换器
*/
public SimpleHash getSimpleHash() ...{
sh.put("upperCase", new UpperCaseTransform());
return sh;
}
}
private SimpleHash sh;
public TransformBuilder(SimpleHash sh) ...{
this.sh = sh;
}
/**//*
* 装配转换器
*/
public SimpleHash getSimpleHash() ...{
sh.put("upperCase", new UpperCaseTransform());
return sh;
}
}
这里的upperCase转换器实现,请参考Freemarker的文档的Transform部分。
Method也如此:
public
class
MethodBuilder
implements
IBuilder
...
{
private SimpleHash sh;
public MethodBuilder(SimpleHash sh) ...{
this.sh = sh;
}
/**//*
* 装配模板方法
*/
public SimpleHash getSimpleHash() ...{
sh.put("indexOf", new IndexOfMethod());
return sh;
}
}
private SimpleHash sh;
public MethodBuilder(SimpleHash sh) ...{
this.sh = sh;
}
/**//*
* 装配模板方法
*/
public SimpleHash getSimpleHash() ...{
sh.put("indexOf", new IndexOfMethod());
return sh;
}
}
还有一些上下文:
public
class
ContextBuilder
implements
IBuilder
...
{
private SimpleHash sh;
private HttpServletRequest request;
public ContextBuilder(SimpleHash sh, HttpServletRequest request) ...{
this.sh = sh;
this.request = request;
}
public SimpleHash getSimpleHash() ...{
Enumeration e = request.getAttributeNames();
while (e.hasMoreElements()) ...{
String name = (String) e.nextElement();
// 忽略freemarker上下文
if (name.indexOf(".freemarker") != 0) ...{
sh.put(name, request.getAttribute(name));
}
}
return sh;
}
}
private SimpleHash sh;
private HttpServletRequest request;
public ContextBuilder(SimpleHash sh, HttpServletRequest request) ...{
this.sh = sh;
this.request = request;
}
public SimpleHash getSimpleHash() ...{
Enumeration e = request.getAttributeNames();
while (e.hasMoreElements()) ...{
String name = (String) e.nextElement();
// 忽略freemarker上下文
if (name.indexOf(".freemarker") != 0) ...{
sh.put(name, request.getAttribute(name));
}
}
return sh;
}
}
然后在web.xml里把原来配置的freemarker.ext.servlet.FreemarkerServlet改为自己的类:xxx.xxx.xxx.BaseServlet
这样就可以了。
比如代码所示,则每请求一个ftl文件都会装载core.ftl模板,然后预先加载转换器upperCase和模板方法indexOf和其他上下文。