/**
* 快速SSI框架 使用时,须派生子类并重写相应的方法
*/
public abstract class SimpleSSI implements Filter
{
// 单一实例
protected Configuration frmkConfig;
public void init(FilterConfig fConfig) throws ServletException
{
// 获取app所在目录
File appRoot = new File(fConfig.getServletContext().getRealPath("/"));
// 初始化FreeMarker配置
try
{
frmkConfig = new Configuration(Configuration.VERSION_2_3_28);
frmkConfig.setDirectoryForTemplateLoading(appRoot);// 设置模板根目录
frmkConfig.setDefaultEncoding("UTF-8");
frmkConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
frmkConfig.setLogTemplateExceptions(false);
} catch (Exception e)
{
// TODO: handle exception
}
}
public void destroy()
{
}
// 子类重写这个方法,决定是否作为SSI处理
protected abstract boolean useSSI(HttpServletRequest request, String servletPath);
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 解析出ServletPath
// 注意:不能使用getServletPath()方法,因为当匹配路径规则为 /path/*时,无法得到真正的路径
String contextPath = request.getServletContext().getContextPath();
String requestUri = request.getRequestURI();
String servletPath = requestUri.substring(contextPath.length());
System.out.println("servletPath: "+servletPath);
// 允许部分路径不使用SSI
if (!useSSI(request, servletPath))
{
chain.doFilter(req, resp);
return;// 此文件不使用SSI,直接放行
}
// 首次运行时,加载HTML文件,解析预处理得到Template对象,并存到Configuration内的Template Cache里
// 再次运行时,直接从Template Cache获取Template对象
Template tp = null;
try
{
tp = frmkConfig.getTemplate(servletPath);
} catch (TemplateNotFoundException e)
{
response.sendError(404, "File Not Exist:" + servletPath);
return;// 目标HTML不存在,则直接返回404
}
// 处理并返回应答
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
Writer writer = response.getWriter();
Map<String, Object> model = new HashMap<String, Object>();
try
{
tp.process(model, writer);// 输出给客户端
} catch (TemplateException e)
{
e.printStackTrace();
response.sendError(500, e.getMessage());
} finally
{
writer.close();
}
}
}
使用:
1.派生子类,重写useSSI()方法,useSSI() 里进一步过滤,决定当前URL是否需要SSI处理。
2.添加注解@WebFilter,指定URL Pattern。
例如上一个例子改写:
@WebFilter("*.html")
public class MySSI extends SimpleSSI
{
/** 进一步对URL进行过滤
* 返回 true,表示此URL使用SSI处理<#include>指令
* 返回 false, 表示此URL页面不需要SSI处理
*/ @Override
protected boolean useSSI(HttpServletRequest request, String servletPath)
{
return true;
}
}