`

初识servlet中过滤器

阅读更多

对于Web应用程序来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端与资源之间的请求与相应信息,并对这些信息进行过滤

执行顺序是:当Web服务器接收到对资源文件的请求时,先判断是否有与该资源文件关联的过滤器,如果有,那么容器讲请求先交个过滤器进行处理,过滤器处理完后再转交给目标资源。当目标资源对请求作出响应时,容器同样会将响应先交给过滤器处理,最后再将响应发给客户端。

当部署了多个过滤器时就组成了过滤器链,过滤器依次对请求做处理,交给目标资源,然后再按照相反的顺序处理响应信息,直到客户端。

过滤器并不是必须将请求交给目标资源或下一个过滤器,它可以自行处理请求,然后发送响应到客户端,或者将请求交给另一个目标资源。

与过滤器相关的接口和类主要有以下几个:

 

具体各类解释可参考j2ee api(简单记载以下,通过继承HttpServletRequestWrapper类可以重写getParameter方法,从而可以对请求的参数做一些特殊处理,通过继承HttpServletResponseWrapper类可以将响应流暂时存放到内存中,从而对响应留做一些替换处理后再发送到浏览器显示)

Servlet容器对部署描述符中声明的每一个过滤器只会创建一个实例。与Servlet类似,容器将在同一个过滤器实例上运行多个线程同时为多个请求服务,因此开发过滤器时也要注意线程安全问题。

<filter-mapping>中可以包含0到4个<dispatcher>元素,该元素指定过滤器对应的请求方式,可以使REQUESR、Include、Forward和Error四种之一,默认为Request(如果目标资源是通过RequestDispatcher的include或forward方法访问时,那么该过滤器不被调用)。

以下由一个例子来解释过滤器和目标资源之间的处理顺序:

a.jsp

<%
     response.sendRedirect("b.jsp");
     System.out.println(3);
%>

b.jsp

<%
	System.out.println(4);
%>

myfilter

System.out.println(1);
chain.doFilter(request,response);
System.out.println(2);

web.xml中对调用a、b页面都设置了过滤器(默认request模式)

当在浏览器中输入对a.jsp的访问地址后,后台打印顺序是1、3、2、1、4、2

这里涉及到sendRedirect的原理了,它其实是向浏览器发送一个特殊的Header,然后由浏览器来做转向,转到指定的页面(用sendRedirect时浏览器的地址栏上可以看到地址的变化。而用jsp:forword则不会),也就是说sendRedirect相当于浏览器又向服务器发送了一个新的请求,那么就不难理解为何打印书序如上了。 

这里,我们将a.jsp改为如下

<%
     //response.sendRedirect("b.jsp");
     System.out.println(3);
%>
<jsp:forward   page="b.jsp"/>

 这样一来打印顺序就变了1、3、1、4、2、2。

为什么会这样呢?同样要从jsp:forward的实现原理来分析,sendRedirect方式相当于浏览器接收到了响应之后又向服务器发送了一次请求,所以相当于两次请求,而jsp:forward方式则相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,最本质的特点就是两次请求共享了reques对象和response对象

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics