4.一个简易的SSI框架——基于Filter实现

/**
 * 快速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;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值