- 浏览: 890640 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (687)
- java (127)
- servlet (38)
- struts (16)
- spring (22)
- hibernate (40)
- javascript (58)
- jquery (18)
- tomcat (51)
- 设计模式 (6)
- EJB (13)
- jsp (3)
- oracle (29)
- RUP (2)
- ajax (3)
- java内存管理 (4)
- java线程 (12)
- socket (13)
- path (5)
- XML (10)
- swing (2)
- UML (1)
- JBPM (2)
- 开发笔记 (45)
- Note参考 (15)
- JAXB (4)
- Quartz (2)
- 乱码 (2)
- CSS (2)
- Exception (4)
- Tools (7)
- sqlserver (3)
- DWR (7)
- Struts2 (47)
- WebService (2)
- 问题解决收藏 (7)
- JBOSS (7)
- cache (10)
- easyUI (19)
- jQuery Plugin (11)
- FreeMarker (6)
- Eclipse (2)
- Compass (2)
- JPA (1)
- WebLogic (1)
- powerdesigner (1)
- mybatis (1)
最新评论
-
bugyun:
受教了,谢谢
java 正则表达式 过滤html标签 -
xiongxingxing_123:
学习了,感谢了
java 正则表达式 过滤html标签 -
wanmeinange:
那如果无状态的。对同一个任务并发控制怎么做?比如继承Quart ...
quartz中参数misfireThreshold的详解 -
fanjieshanghai:
...
XPath 元素及属性查找 -
tianhandigeng:
还是没明白
quartz中参数misfireThreshold的详解
最近需要在项目中做一个缓存框架,通过插件方式加入,要求可以通过配置文件,指定需要缓存页面的URL。
于是就想到做一个拦截器Filter。
该Filter可以首先拦截所有的请求,然后取得请求的URL,与配置中的需要缓存的URL对比,如果需要缓存,则进入缓存处理,如果不需要缓存,则直接到下一个Fitler。
具体的缓存处理,采用开源框架OScache。
方案还是比较简单的。 测试中发现,一般的Fitler只能拦截到从浏览器地址栏中过来的请求。 而页面的采用<jsp:include>方式载入的请求页面,则不能拦截到。
查看相关资料http://www.ibm.com/developerworks/java/library/j-tomcat2/ 后,得出结论:
在Servlet2.3中,Fitler是不能拦截include, forward, error 方式发来的请求的。
在Serlvet2.4中,则增强了Filter的功能,使之可以拦截到上面说的三个请求。 不过需要在配置文件中增加一个配置。
<filter>
该方式,不能拦截到 include 请求。
- <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>
修改如下:
在配置文件,增加 <dispatcher></dispatcher>配置:
- <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>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¶m1=test1 然后再 index.jsp页面中有一个 <jsp:include page="/main.jsp?type2=include¶m2=test2"/>
当访问 /index.jsp?type1=request¶m1=test1 时,使用上面的方法拦截到 include请求 /main.jsp?type2=include¶m2=test2
Filter中的 在取得该请求的所有参数的时候,会将 /index.jsp的参数(type1=request¶m1=test1)也读出来
该方法返回的结果为: /main.jsp?type2=include¶m2=test2&type1=request¶m1=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();
- }
- }
这样就取得了包含,index.jsp的参数。
我现在想要只想要取得 include请求的参数,即 /main.jsp?type2=include¶m2=test2 的参数部分type2=include¶m2=test2
但是通过 request.getParameter()方法,是无法判断出哪个参数才是 include 请求的参数。
经过上面的启发,于是又想到了,是不是有别的AttributeName 可以仅取到 include 请求的参数呢?
通过测试,果然发现的确有该AttributeName:"javax.servlet.include.query_string"
只要通过一句话便可以得到该 参数字符串:
该结果即为:type2=include¶m2=test2 正是需要的仅为 include 请求的参数。
- (String)request.getAttribute("javax.servlet.include.query_string");
发表评论
-
java解决网站静态页面生成方案(源码)
2012-07-01 01:51 0提升网站性能的方式有很多,例如有效的使用缓存,生成静态页 ... -
Servlet映射的匹配原则,优先级
2012-06-08 22:45 1453一个元素用于映射一个已经注册的Servlet的一个对外访问 ... -
TOMCAT SESSION的持久化方法
2012-06-12 09:56 1291Tomcat5.5.12 实现Session持久化的配置: ... -
Servlet和filter的JAVAEE的配置
2012-06-05 22:52 888一、servlet容器对url的匹配过程: 当一个请求发送 ... -
tomcat 静态资源处理类DefaultServlet&Apache静态资源服务
2012-06-05 21:13 2332DefaultServlet是tomcat中用来处理静态资源和 ... -
如何获取搜索引擎的来源和其中的关键字
2011-08-30 21:39 1821在做商务E流量分析的时候,需要实现一个功能:如果访客是通过搜索 ... -
RequestDispatcher接口中的include()方法和forward()方法的区别
2011-04-19 15:34 1171请求转发中 RequestDispatcher 接口中的 in ... -
文件上传下载(oreilly之MultipartReques)
2011-04-10 22:36 1245上传篇代码片段: import com.oreill ... -
使用jstl还要在web.xml里面配一下
2011-01-30 11:26 1939悲剧,有人说是不用apac ... -
JAVA WEB学习笔记(五)-自定义JSP标签
2011-01-27 13:28 822一、基本概念:********** ... -
<转>web.xml 中的listener、 filter、servlet 加载顺序及其详解
2010-12-10 22:45 919转载自 ailongni 最终编 ... -
web.xml里listener、filter和servlet加载顺序和详解(二)
2010-12-10 22:44 1239相应元素配置 1、Web应用图标:指出IDE和GUI工具用来 ... -
转】servlet中web.xml配置详解(转)
2010-12-10 22:42 880转载自 limpid1215 最终编辑 limpid121 ... -
Tomcat6中启用invoker心得
2010-10-26 08:31 1584今天下了看了一下示例,TOMCAT6中启用invoker 访问 ... -
el表达式不起作用的解决方案
2010-10-12 14:18 881关键字: el表达式不起作用 今天晚上学习SSH,发现一个el ... -
getOutputStream() has already been called for this response
2010-10-11 16:15 1271java.lang.IllegalStateException ... -
关于serveletContext.getRealPath()方法
2010-10-11 10:23 20451.关于request.getRealPath 问 ... -
采用application/vnd.ms-excel导出excel时修改文件名
2010-09-26 10:17 3908设置response属性,如下 response.se ... -
HttpServletResponse addHeader 与 setHeader 区别
2010-09-09 19:09 3880setHeader(name,value) :如果Header ... -
web.xml配置详解
2010-09-09 09:47 750转自:http://blog.csdn.net/j ...
相关推荐
Filter 或者目标 Servlet 程序去处理,也可以直接向客户端返回响应信息,或者利用 RequestDispatcher 的 forward() 和 include() 方法,以及 HttpServletResponse 的 sendRedirect() 方法将请求转向到其他资源。...
Filter是一种特殊的Java类,能够拦截客户端到服务器端的请求和服务器响应,对数据进行预处理或者后处理。在这个主题中,我们将深入探讨Filter的映射及其在web.xml文件中的配置,以及它们如何与Servlet容器交互。 ...
- **过滤**:通过实现`doFilter()`方法,Filter可以拦截请求和响应,进行预处理或后处理。 - **销毁**:在Filter不再使用时,服务器会调用`destroy()`方法。 在`FilterDemo`这个例子中,我们可以创建一个自定义的...
可以通过多个`<filter-mapping>`元素为一个Filter配置不同的拦截规则,也可以通过`<dispatcher>`元素指定Filter在请求的不同阶段(如FORWARD、INCLUDE、ERROR等)发挥作用。 【监听器(Listener)简介】 监听器...
- 可以通过`<dispatcher>`元素指定`Filter`是否应用于特定的请求分派器类型,如`INCLUDE`、`FORWARD`等。 2. **批量设置请求编码** 一个常见的应用场景是批量设置请求的编码格式。例如,下面的示例展示了如何...
Java Filter 是Java Servlet API 中的一个重要概念,它允许开发者在请求到达目标Servlet或者JSP之前进行拦截处理,以及在响应返回给客户端之后进行后处理。这个功能在软件开发中广泛应用于日志记录、权限控制、数据...
在`web.xml`中,我们需要配置`<filter>`和`<filter-mapping>`元素来指定`LogFilter`的类名和需要拦截的URL模式。例如: ```xml <filter> <filter-name>LogFilter</filter-name> <filter-class>...
Filter(过滤器)是Java Web开发中的一个重要组件,它主要用于拦截用户请求,在请求达到目标资源(如Servlet或JSP页面)之前进行预处理,或者在响应返回客户端之前进行后处理。通过Filter可以实现诸如权限验证、编码...
【Java Filter过滤器详解】 Java Filter是Java Servlet...总的来说,Java Filter提供了一种灵活的方式来增强Web应用程序的功能,通过在请求和响应之间插入自定义逻辑,可以在不修改原有代码的情况下实现多种扩展需求。
在Web应用程序中,Filter允许开发者在请求到达Servlet之前和响应离开Servlet之后进行拦截和处理,增强了应用的灵活性和可扩展性。 一、Filter的生命周期与配置 Filter遵循一定的生命周期,包括`init()`、`doFilter...
在`<filter-mapping>`中,`<dispatcher>`元素用于指定Filter拦截资源的方式,常见的值有REQUEST、INCLUDE、FORWARD和ERROR,分别对应不同的请求处理阶段。例如,REQUEST表示用户直接访问,INCLUDE表示通过`...
通过这种方式,过滤器能够有效地拦截和修改请求或响应的信息。 - **过滤器的作用**: - **拦截请求**:在请求到达Servlet之前,过滤器可以对其进行拦截,从而实现对请求内容的检查或修改。 - **修改请求**:过滤...
- **DispatcherTypes**:Filter可以拦截多种类型的请求,如REQUEST、FORWARD、INCLUDE、ERROR等,这使得Filter能应用于各种场景。 3. **配置Filter** 在web.xml中,我们需要定义Filter的映射,包括Filter的类名、...
* Filter 链中各个 Filter 执行请求时的拦截顺序与响应时的拦截顺序相同。 六、Session 配置 * 在 web.xml 中,<session-config> 元素用于配置 Session 的超时时间。 * 在空闲状态下,Session 对象的销毁是根据 ...
- 在`web.xml`文件中,可以通过在`<filter-mapping>`元素内的`<url-pattern>`子元素中使用通配符“*”,来配置过滤器拦截所有请求。这种方式非常灵活且方便,特别适用于需要对所有请求进行相同预处理或后处理的情况...
-- 指定哪些URL模式会被此Filter拦截 --> <dispatcher>request <dispatcher>forward <dispatcher>include <!-- 指定Filter在请求分发过程中的作用范围 --> </filter-mapping> ``` #### 二、CharArrayWriter和...
- `<url-pattern>`:使用正则表达式指定Filter拦截的请求路径。 - `<servlet-name>`:指定Filter拦截的Servlet名称。 - `<dispatcher>`:定义Filter何时被调用,可选值有REQUEST, INCLUDE, FORWARD, 和 ERROR。 ...
过滤器可以在请求到达目标资源(如Servlet、JSP)之前或之后拦截请求和响应。通过实现`doFilter()`方法,我们可以定义过滤器的行为。 2. **过滤器生命周期** 过滤器有三个关键方法:`init()`, `doFilter()`, 和 `...
过滤器的主要功能是对请求和响应进行预处理和后处理,允许开发者在请求到达目标资源之前和响应离开应用程序之后进行拦截,执行诸如认证、日志记录、参数处理、压缩等任务。 1. **过滤器的工作原理** 过滤器的工作...