为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > Filter拦截include方式的请求

Filter拦截include方式的请求

2018-03-16 9页 doc 25KB 10阅读

用户头像

is_037433

暂无简介

举报
Filter拦截include方式的请求Filter拦截include方式的请求 最近需要在项目中做一个缓存框架,通过插件方式加入,要求可以通过配置文件,指定需要缓存页面的URL。 于是就想到做一个拦截器Filter。 该Filter可以首先拦截所有的请求,然后取得请求的URL,与配置中的需要缓存的URL对 比,如果需要缓存,则进入缓存处理,如果不需要缓存,则直接到下一个Fitler。 具体的缓存处理,采用开源框架OScache。 方案还是比较简单的。 测试中发现,一般的Fitler只能拦截到从浏览器地址栏中过来的请 求。 而页面的采用;方式载入的请求页面...
Filter拦截include方式的请求
Filter拦截include方式的请求 最近需要在项目中做一个缓存框架,通过插件方式加入,要求可以通过配置文件,指定需要缓存页面的URL。 于是就想到做一个拦截器Filter。 该Filter可以首先拦截所有的请求,然后取得请求的URL,与配置中的需要缓存的URL对 比,如果需要缓存,则进入缓存处理,如果不需要缓存,则直接到下一个Fitler。 具体的缓存处理,采用开源框架OScache。 还是比较简单的。 测试中发现,一般的Fitler只能拦截到从浏览器地址栏中过来的请 求。 而页面的采用<;jsp:include>;方式载入的请求页面,则不能拦截到。 查看相关资料后,得出 结论: 在Servlet2.3中,Fitler是不能拦截include, forward, error 方式发来的请求的。 在Serlvet2.4中,则增强了Filter的功能,使之可以拦截到上面说的三个请求。 不过需 要在配置文件中增加一个配置。 <;filter>; <;filter-name>;Cache<;/filter-name>; <;filter-class>;prx.cache.filter.CacheFilter<;/filter-class>; <;init-param>; <;!-- 过期时间设置,默认为60秒 -->; <;param-name>;refreshPeriod<;/param-name>; <;param-value>;120<;/param-value>; <;/init-param>; <;/filter>; <;filter-mapping>; <;filter-name>;Cache<;/filter-name>; <;url-pattern>;/*<;/url-pattern>; <;/filter-mapping>; 该方式,不能拦截到 include 请求。 修改如下: <;filter>; <;filter-name>;Cache<;/filter-name>; <;filter-class>;prx.cache.filter.CacheFilter<;/filter-class>; <;init-param>; <;!-- 过期时间设置,默认为60秒 -->; <;param-name>;refreshPeriod<;/param-name>; <;param-value>;120<;/param-value>; <;/init-param>; <;/filter>; <;filter-mapping>; <;filter-name>;Cache<;/filter-name>; <;url-pattern>;/index.jsp<;/url-pattern>; <;dispatcher>;request<;/dispatcher>; <;!-- 使得页面中通过 include 方式嵌入的匹配页面也可以通过该Filter -->; <;dispatcher>;include<;/dispatcher>; <;/filter-mapping>; 在配置文件,增加 <;dispatcher>;<;/dispatcher>;配置: <;dispatcher>;request <;/dispatcher>; Filter 只能拦截 匹配的 request 方式 的请求,为默认值 。 <;dispatcher>;include <;/dispatcher>; Filter 只能拦截 匹配的 incldue 方 式的请求 <;dispatcher>;forward <;/dispatcher>; Filter 只能拦截 匹配的 forward 方式 的请求 <;dispatcher>;error <;/dispatcher>; Filter 只能拦截 匹配的 error 方式的请求 dispatcher可以配置多个,用来组合各种需求。 例如:上面的配置,Fitler可以拦截 request和include 方式的请求。 通过以上的配置,就可以是Filter拦截到 include 的请求了。(当然,tomcat需要支持 servlet2.4) 到此解决了问题一。 在后来的测试又发现,虽然Filter是拦截了 incldue 的请求,但是在 Fitler 中,却无法 取得该 incldue 的URL 由于项目的缓存方案是需要,取得URL请求,然后再判断是否需要缓存。 所以必须取得该 include 请求的URL。 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest)request; //取的url相对地址,例如:/PrxWebCache/index.jsp String url = httpRequest.getRequestURI(); System.out.println(url); int cacheGrade = CacheUtils.isNeedCacheUrl(url); if(cacheGrade != 0) { //是否是需要缓存的url String key = CacheUtils.createKeyByUrl(httpRequest); boolean isInCache = CacheUtils.isInCache(httpRequest, key, cacheGrade); if(isInCache) { try { String content = (String)CacheUtils.getFromCache(httpRequest, key, cacheGrade, refreshPeriod); System.out.println(";缓存";); response.getWriter().print(content); } catch (NeedsRefreshException e) { //过 期,需要刷新 System.out.println(";刷新";); cacheAndResponseContent(httpRequest, response, chain, key, cacheGrade); } } else { //拦截响应数据,先加入缓存,再响应给客户端 cacheAndResponseContent(httpRequest, response, chain, key, cacheGrade); } } else { chain.doFilter(request, response); } } 在Filter中,通过 httpRequest.getRequestURI(); 取出的 URL: 1. 当是 request 请求时,取得的 URL 是正确的。 2. 当是 include 请求时, 取得的 URL 是 包含该 include 元素的原页面的 URL 比如: 在 main.jsp 页面中 有个 <;jsp:include page=";index.jsp?type=test";/>; 当Fitler拦截到 该 include请求时, httpRequest.getRequestURI(); 得出的是 main.jsp 而不是我需要的 index.jsp 但是 通过 httpRequest.getParameter(";type";); 却可以得到 传入的参数 ";test";。 到网上搜个半天,都没有相关。最后在 OScache 源码中发现了一个方法。 httpRequest.getAttribute(";javax.servlet.include.request_uri";) 通过该方法,可以直接取出 include 请求的 URL 值。 至于,这个 ";javax.servlet.include.request_uri"; 参数怎么设置进来的,还没仔细研 究。 时间紧张,先用着,以后再研究吧。 又发现一个问题: 在Filter中拦截到incldue方式的请求后,在取得传入的所有参数的时候,会把request 的 请求参数也读出来。 比如:请求页面 /index.jsp?type1=request&;param1=test1 然后再 index.jsp页面 中有一个 <;jsp:include page=";/main.jsp?type2=include&;param2=test2";/>; 当访问 /index.jsp?type1=request&;param1=test1 时,使用上面的方法拦截到 include请求 /main.jsp?type2=include&;param2=test2 Filter中的 在取得该请求的所有参数的时候,会将 /index.jsp的参数 (type1=request&;param1=test1)也读出来 /** * 返回请求的URL的参数部分,例如:url=/index.jsp?type=1&;searchWord=java, 则返回type=1&;searchWord=java * @param request */ private static String getSortedQueryString(HttpServletRequest request) { Map paramMap = request.getParameterMap(); if (paramMap.isEmpty()) { return null; } Set paramSet = new TreeMap(paramMap).entrySet(); StringBuffer buf = new StringBuffer(); boolean first = true; for (Iterator it = paramSet.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String[] values = (String[]) entry.getValue(); for (int i = 0; i <; values.length; i++) { String key = (String) entry.getKey(); if ((key.length() != 10) || !";jsessionid";.equals(key)) { if (first) { first = false; } else { buf.append('&;'); } buf.append(key).append('=').append(values[i]); } } } // We get a 0 length buffer if the only parameter was a jsessionid if (buf.length() == 0) { return null; } else { return buf.toString(); } } 该方法返回的结果为: /main.jsp?type2=include&;param2=test2&;type1=request&;param1=test1 这样就取得了包含,index.jsp的参数。 我现在想要只想要取得 include请求的参数,即 /main.jsp?type2=include&;param2=test2 的参数部分type2=include&;param2=test2 但是通过 request.getParameter()方法,是无法判断出哪个参数才是 include 请求的参数。 经过上面的启发,于是又想到了,是不是有别的AttributeName 可以仅取到 include 请求 的参数呢, 通过测试,果然发现的确有该AttributeName:";javax.servlet.include.query_string"; 只要通过一句话便可以得到该 参数字符串: (String)request.getAttribute(";javax.servlet.include.query_string";); 该结果即为:type2=include&;param2=test2 正是需要的仅为 include 请求的参数。 本文出自
/
本文档为【Filter拦截include方式的请求】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索