1. 什么是过滤器

过滤器是一个运行在服务器端的程序,先于与之相关的servlet或JSP页面之前运行实现对请求资源的过滤的功能;

过滤器可附加到一个或多个servlet或jsp页面上,可以检查请求信息也可以处理相应信息;

filter的基本功能是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet执行前后实现一些特殊的功能。

过滤器 response_xml

如图,浏览器发出的请求先递交给第一个filter进行过滤,符合规则则放行,递交给filter链中的下一个过滤器进行过滤。过滤器在链中的顺序与它在web.xml中配置的顺序有关,配置在前的则位于链的前端。当请求通过了链中所有过滤器后就可以访问资源文件了,如果不能通过,则可能在中间某个过滤器中被处理掉。

在doFilter()方法中,chain.doFilter()前的一般是对request执行的过滤操作,chain.doFilter后面的代码一般是对response执行的操作。过滤链代码的执行顺序如下:

过滤器 response_java_02

 过滤器一般用于登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换等等操作,便于代码重用,不必每个servlet中还要进行相应的操作。

 

2. 过滤器的编写流程

  • 实现类,需要实现接口javax.servlet.Filter;

过滤器 response_xml_03

过滤器 response_java_04

1 package com.eagle.web;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 public class ServletFilter extends HttpServlet {
10 
11     private static final long serialVersionUID = 1L;
12 
13     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14         String name = (String) request.getAttribute("name");
15         System.out.println("servlet获取request域中的name属性="+name);
16         response.getWriter().write("hello haohao...name="+name);
17     }
18 
19     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
20         doGet(request, response);
21     }
22 }

ServletFilter

过滤器 response_xml_03

过滤器 response_java_04

1 package com.eagle.filter;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.Filter;
 5 import javax.servlet.FilterChain;
 6 import javax.servlet.FilterConfig;
 7 import javax.servlet.ServletException;
 8 import javax.servlet.ServletRequest;
 9 import javax.servlet.ServletResponse;
10 
11 public class Demo1Filter implements Filter {
12 
13     public Demo1Filter() {
14 
15     }
16 
17     public void init(FilterConfig fConfig) throws ServletException {
18 
19     }
20 
21     public void destroy() {
22 
23     }
24 
25     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
26             throws IOException, ServletException {
27         request.setAttribute("name", "filter");
28         System.out.println("servlet之前进行调用,设置request域的name属性为filter");
29         chain.doFilter(request, response);
30     }
31 }

Demo1Filter

  • 配置,在web.xml使用<filter>和<filter-mapping>进行配置。

过滤器 response_xml_03

过滤器 response_java_04

1 <filter>
2     <display-name>Demo1Filter</display-name>
3     <filter-name>Demo1Filter</filter-name>
4     <filter-class>com.eagle.filter.Demo1Filter</filter-class>
5   </filter>
6   <filter-mapping>
7     <filter-name>Demo1Filter</filter-name>
8     <url-pattern>/*</url-pattern>
9   </filter-mapping>

web.xml

过滤器 response_html_09

过滤器 response_xml_10

3. 配置web.xml详解

<filter>
  <filter-name>loginFilter</filter-name>          //过滤器名称
  <filter-class>com.x.control.loginFilter</filter-class>       //过滤器类的包路径
  <init—param>                        //可选
    <param—name>参数名</param-name>          //过滤器初始化参数
    <param-value>参数值</param-value>
  </init—pamm>
</filter>

<filter-mapping>                     //过滤器映射
  <filter-name>loginFilter</filter-name>
  <url-pattern>指定过滤器作用的对象</url-pattern>

</filter-mapping>

在配置中需要注意的有两处:

  • 一是<filter-class>指明过滤器类所在的包路径。
  • 二是<url-pattren>处定义过滤器作用的对象。一般有以下规则:

    1:作用于所有web资源:<url—pattern>/*</url-pattern>。则客户端请求访问任意资源文件时都要经过过滤器过滤,通过则访问文件,否则拦截。

    2:作用于某一文件夹下所有文件:<url—pattern>/dir/*</url-pattern>

    3:作用于某一种类型的文件:<url—pattern>*.扩展名</url-pattern>。比如<url—pattern>*.jsp</url-pattern>过滤所有对jsp文件的访问请求。

    4:作用于某一文件夹下某一类型文件:<url—pattern>/dir/*.扩展名</url-pattern>

    如果一个过滤器需要过滤多种文件,则可以配置多个<filter-mapping>,一个mapping定义一个url-pattern来定义过滤规则。

 

4. 过滤器实现设置字符编码问题

  • 编写测试jsp

过滤器 response_xml_03

过滤器 response_java_04

1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11 <form action="${ pageContext.request.contextPath }/Login" method="post">
12     <table border="0px">
13         <tr>
14             <td>用户名:</td>
15             <td><input type="text" name="username" id="username" placeholder="请输入用户名" /></td>
16         </tr>
17         <tr>
18             <td>密码:</td>
19             <td><input type="password" name="password" id="password" placeholder="请输入密码" /></td>
20         </tr>
21         <tr>
22             <td colspan="2"><input type="submit" value="提交" /></td>
23         </tr>
24     </table>
25 </form>
26 </body>
27 </html>

postcharacter.jsp

  • 编写测试servlet

过滤器 response_xml_03

过滤器 response_java_04

package cn.eagle.web;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Login extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username="+username+";password"+password);
        response.getWriter().write("hello haohao..."+"username="+username+";password"+password+"张三");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

Login

  • 编写filter

过滤器 response_xml_03

过滤器 response_java_04

1 package cn.eagle.filter;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.Filter;
 5 import javax.servlet.FilterChain;
 6 import javax.servlet.FilterConfig;
 7 import javax.servlet.ServletException;
 8 import javax.servlet.ServletRequest;
 9 import javax.servlet.ServletResponse;
10 
11 public class MyRequestCharacterFilter implements Filter {
12 
13     public MyRequestCharacterFilter() {
14 
15     }
16 
17     public void init(FilterConfig fConfig) throws ServletException {
18 
19     }
20 
21     public void destroy() {
22 
23     }
24 
25     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
26             throws IOException, ServletException {
27         request.setCharacterEncoding("utf-8");
28         response.setCharacterEncoding("utf-8");
29         response.setContentType("text/html;charset=utf-8");
30         chain.doFilter(request, response);
31     }
32 }

MyRequestCharacterFilter

  • web.xml配置filter

过滤器 response_xml_03

过滤器 response_java_04

1   <filter>
2     <display-name>MyRequestCharacterFilter</display-name>
3     <filter-name>MyRequestCharacterFilter</filter-name>
4     <filter-class>cn.eagle.filter.MyRequestCharacterFilter</filter-class>
5   </filter>
6   <filter-mapping>
7     <filter-name>MyRequestCharacterFilter</filter-name>
8     <url-pattern>/*</url-pattern>
9   </filter-mapping>

web.xml

过滤器 response_html_19

过滤器 response_html_20

 

5. 解决post和get方式乱码问题

  • 编写自己的request类,该类实现HttpServletRequestWrapper,并重写getParameter()方法;

过滤器 response_xml_03

过滤器 response_java_04

1 package cn.eagle.domain;
 2 
 3 import java.io.UnsupportedEncodingException;
 4 
 5 import javax.servlet.http.HttpServletRequest;
 6 import javax.servlet.http.HttpServletRequestWrapper;
 7 
 8 public class MyRequest extends HttpServletRequestWrapper {
 9 
10     public MyRequest(HttpServletRequest request) {
11         super(request);
12 
13     }
14 
15     @Override
16     public String getParameter(String name) {
17 
18         String value = super.getParameter(name);
19         try {
20             if ("GET".equalsIgnoreCase(this.getMethod())) {
21                 value = new String(value.getBytes("ISO8859-1"), "UTF-8");
22             }
23         } catch (Exception e) {
24             throw new RuntimeException();
25         }
26         return value;
27     }
28 
29 }

MyRequest

  • 编写filter,传递自己的request对象;

过滤器 response_xml_03

过滤器 response_java_04

1 package cn.eagle.filter;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.Filter;
 5 import javax.servlet.FilterChain;
 6 import javax.servlet.FilterConfig;
 7 import javax.servlet.ServletException;
 8 import javax.servlet.ServletRequest;
 9 import javax.servlet.ServletResponse;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 
13 import cn.eagle.domain.MyRequest;
14 
15 public class EncodingFilter implements Filter {
16 
17     public EncodingFilter() {
18 
19     }
20 
21     public void init(FilterConfig fConfig) throws ServletException {
22 
23     }
24 
25     public void destroy() {
26 
27     }
28 
29     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
30             throws IOException, ServletException {
31         HttpServletRequest request = (HttpServletRequest) req;
32         HttpServletResponse response = (HttpServletResponse) resp;
33         // 设置编码
34         request.setCharacterEncoding("utf-8");
35         response.setCharacterEncoding("utf-8");
36         response.setContentType("text/html;charset=utf-8");
37         // 创建自定义request
38         MyRequest myRequest = new MyRequest(request);
39         chain.doFilter(myRequest, response);
40     }
41 }

EncodingFilter

  • 编写servlet进行测试。

过滤器 response_xml_03

过滤器 response_java_04

1 package cn.eagle.web;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 public class Encoding extends HttpServlet {
10 
11     private static final long serialVersionUID = 1L;
12 
13     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14         String username = request.getParameter("username");
15         System.out.println(username);
16         response.getWriter().write("hello haohao..."+username);
17     }
18 
19     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
20         doGet(request, response);
21     }
22 }

Encoding

过滤器 response_过滤器 response_27

过滤器 response_java_28