`

FilterChain 执行过程(转)

阅读更多
下面是一个避免提交数据乱码问题的EncodingFilter:

   1. package anni; 
   2. import java.io.IOException; 
   3. import javax.servlet.Filter; 
   4. import javax.servlet.FilterChain; 
   5. import javax.servlet.FilterConfig; 
   6. import javax.servlet.ServletException; 
   7. import javax.servlet.ServletRequest; 
   8. import javax.servlet.ServletResponse; 
   9. public class EncodingFilter implements Filter { 
  10. public void init(FilterConfig config) throws ServletException {} 
  11. public void destroy() {} 
  12. public void doFilter(ServletRequest request, 
  13. ServletResponse response, 
  14. FilterChain chain) 
  15. throws IOException, ServletException { 
  16. request.setCharacterEncoding("gb2312"); 
  17. chain.doFilter(request, response); 
  18. } 
  19. } 

package anni; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class EncodingFilter implements Filter { public void init(FilterConfig config) throws ServletException {} public void destroy() {} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("gb2312"); chain.doFilter(request, response); } }

相应的web.xml为:

   1. <filter> 
   2. <filter-name>EncodingFilter</filter-name> 
   3. <filter-class>anni.EncodingFilter</filter-class> 
   4. </filter> 
   5. <filter-mapping> 
   6. <filter-name>EncodingFilter</filter-name> 
   7. <url-pattern>/*</url-pattern> 
   8. </filter-mapping> 

<filter> <filter-name>EncodingFilter</filter-name> <filter-class>anni.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

过滤控制访问权限的SecurityFilter:

   1. public void doFilter(ServletRequest request, 
   2. ServletResponse response, 
   3. FilterChain chain) 
   4. throws IOException, ServletException { 
   5. HttpServletRequest req = (HttpServletRequest) request; 
   6. HttpServletResponse res = (HttpServletResponse) response; 
   7. HttpSession session = req.getSession(); 
   8. if (session.getAttribute("username") != null) { 
   9. chain.doFilter(request, response); 
  10. } else { 
  11. res.sendRedirect("../failure.jsp"); 
  12. } 
  13. } 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(); if (session.getAttribute("username") != null) { chain.doFilter(request, response); } else { res.sendRedirect("../failure.jsp"); } }

相应的web.xml为:

   1. <filter> 
   2. <filter-name>SecurityFilter</filter-name> 
   3. <filter-class>anni.SecurityFilter</filter-class> 
   4. </filter> 
   5. <filter-mapping> 
   6. <filter-name>SecurityFilter</filter-name> 
   7. <url-pattern>/admin/*</url-pattern> 
   8. </filter-mapping> 

<filter> <filter-name>SecurityFilter</filter-name> <filter-class>anni.SecurityFilter</filter-class> </filter> <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/admin/*</url-pattern> </filter-mapping>

EncodingFilter负责设置编码,SecurityFilter负责控制权限,那这两个过滤器是怎么起作用的呢?它们两个同时过滤一个请求时谁先谁后呢?

所有的奥秘就在Filter中的FilterChain中。服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的 doFilter()方法。执行的顺序就如上图所示,执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的 chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的 chain.doFilter()之后的代码,最后返回响应。

因此在07-02中执行的代码顺序是:

   1.

      执行EncodingFilter.doFilter()中chain.doFilter()之前的部分:request.setCharacterEncoding("gb2312");
   2.

      执行SecurityFilter.doFilter()中chain.doFilter()之前的部分:判断用户是否已登录。

      如果用户已登录,则访问请求的资源:/admin/index.jsp。

      如果用户未登录,则页面重定向到:/failure.jsp。
   3.

      执行SecurityFilter.doFilter()中chain.doFilter()之后的部分:这里没有代码。
   4.

      执行EncodingFilter.doFilter()中chain.doFilter()之后的部分:这里也没有代码。

过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题,像EncodingFilter就一定要放在所有Filter之前,这样才能确保在使用请求中的数据前设置正确的编码。
分享到:
评论

相关推荐

    自定义FilterChain的编写

    在标准的`Filter`实现中,`FilterChain`由容器(如Tomcat)管理,但在自定义的`FilterChain`实现中,我们可以完全掌控这个过程,决定哪些过滤器先执行,哪些后执行。 让我们深入探讨如何自定义`FilterChain`: 1. ...

    工程编码格式转换

    标题"工程编码格式转换"指的是在软件开发过程中,由于不同的文本编辑器、编程语言或操作系统可能采用不同的字符编码方式,为确保代码的正确显示和处理,需要进行编码格式的转换。常见的编码格式有ASCII、UTF-8、GBK...

    YII Framework的filter过滤器用法分析

    在方法内部,调用$filterChain-&gt;run()可以继续后续过滤器与动作的执行。 示例代码: ```php public function filterAccessControl($filterChain) { echo "---&gt;filterAccessControl"; $filterChain-&gt;run(); } ``` ...

    Struts2执行流程 面试常问到

    在请求处理过程中,`ActionContext`存储了与当前请求相关的数据,包括Action上下文、Action实例、值栈等。开发者可以通过`ActionContext.getContext()`获取到它。 9. **结果处理**: - Action执行完成后,`...

    普通的验证码生成过程

    这个过程主要包括以下几个步骤: 1. 定义字符映射表`mapTable`,包含小写字母、大写字母和数字。 2. 创建Servlet方法`getCertPic`,接收宽度、高度和输出流参数。如果未指定宽度和高度,会设置默认值。 3. 使用`...

    JSP中把动态页面转换为静态页面

    当`Filter`拦截到请求时,如果静态HTML文件不存在,会创建`WrappedResponse`实例并调用`filterChain(request, wrappedResponse)`,让请求正常执行但响应被`WrappedResponse`捕获。执行完成后,将`WrappedResponse`...

    使用ANT把一种编码格式转化为另外一种编码格式

    Apache Ant是一个广泛使用的Java构建工具,它提供了强大的灵活性和可扩展性,能够帮助开发者执行各种任务,包括文件编码格式的转换。本篇文章将深入探讨如何使用Ant完成这种转化。 首先,让我们了解编码格式的基础...

    Filter过滤器

    Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊的功能。 在 Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序:Filter, ...

    拦截过滤器模式

    ### 拦截过滤器模式详解 #### 一、概述 **拦截过滤器模式...- **API网关**:在API调用过程中添加额外的安全措施或统计信息收集。 通过这种方式,可以有效地扩展系统的功能,同时保持核心业务逻辑的清晰和简洁。

    过滤器介绍及代码

    过滤器的开发过程相对简单,主要包括以下几个步骤: 1. **编写Java类实现Filter接口**:创建一个Java类,并实现`Filter`接口中的所有方法。最关键的是实现`doFilter`方法,该方法是过滤器的核心逻辑所在。 2. **在...

    六个有用的java过滤器

    ### 六个有用的Java过滤器知识点详解 在Java Web开发中,过滤器(Filter)是一种非常重要的技术,它能够对用户的...在实际项目开发过程中,开发者可以根据自己的需求选择合适的技术方案来构建高效稳定的Web应用程序。

    完整版Java JSP web开发教程 12_过滤器(共20页).ppt

    `doFilter()`方法是核心,它执行实际的过滤操作,同时通过`FilterChain`对象控制过滤器链的执行。 4. **FilterChain与过滤器链** `FilterChain`接口允许过滤器调用下一个过滤器或者直接调用目标资源。通过调用`...

    jsp过滤器及乱码的解决

    确保数据库设置为UTF-8,同时Web页面也需设置为UTF-8,这样可以避免在数据传输和存储过程中出现编码不匹配导致的乱码。 在JSP或JSF应用中,Servlet过滤器(Filter)起着至关重要的作用。Servlet API 2.3版本引入了...

    ant第三部分源码

    2. **任务(Task)**:Ant的任务是构建过程中的最小执行单元,例如`javac`任务用于编译Java源代码,`copy`任务用于复制文件。每个任务都是一个实现了`Task`接口的类,通过`execute()`方法执行具体操作。Ant提供了...

    javaWeb实现事务1

    这样,每个线程在执行过程中都可以访问自己独有的连接,避免了连接在多线程环境中的共享问题,从而减少了并发控制的复杂性。 2. **事务开始**: 在`TransactionFilter`的`doFilter()`方法中,首先从`JDBCTools`类...

    JAVA登录拦截器,查看用户是否登录过,未登录禁止访问页面

    - **放行请求**:如果用户已登录,则调用 `filterChain.doFilter(request, response)` 方法让请求继续执行。 #### 四、应用场景 登录拦截器的应用场景非常广泛,包括但不限于以下几个方面: - **权限管理**:...

    javaFilter自定义编码过滤器

    * 乱码原因:乱码问题可能是由于服务器端和客户端使用不同的编码方式,或者是由于数据传输过程中编码不正确。 * 解决方法:解决乱码问题的方法是使用统一的编码方式,例如 UTF-8,并确保服务器端和客户端使用相同的...

    java过滤器

    在Java Web开发中,过滤器(Filter)是一种非常实用的技术,它可以在客户端发送请求到服务器端的过程中进行一系列的预处理工作,比如设置字符编码、身份认证等。此外,过滤器也可以在服务器返回响应给客户端前做一些...

Global site tag (gtag.js) - Google Analytics