1. 什么是过滤器
过滤器是一个运行在服务器端的程序,先于与之相关的servlet或JSP页面之前运行实现对请求资源的过滤的功能;
过滤器可附加到一个或多个servlet或jsp页面上,可以检查请求信息也可以处理相应信息;
filter的基本功能是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet执行前后实现一些特殊的功能。
如图,浏览器发出的请求先递交给第一个filter进行过滤,符合规则则放行,递交给filter链中的下一个过滤器进行过滤。过滤器在链中的顺序与它在web.xml中配置的顺序有关,配置在前的则位于链的前端。当请求通过了链中所有过滤器后就可以访问资源文件了,如果不能通过,则可能在中间某个过滤器中被处理掉。
在doFilter()方法中,chain.doFilter()前的一般是对request执行的过滤操作,chain.doFilter后面的代码一般是对response执行的操作。过滤链代码的执行顺序如下:
过滤器一般用于登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换等等操作,便于代码重用,不必每个servlet中还要进行相应的操作。
2. 过滤器的编写流程
- 实现类,需要实现接口javax.servlet.Filter;
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
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>进行配置。
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
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
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
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
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
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
5. 解决post和get方式乱码问题
- 编写自己的request类,该类实现HttpServletRequestWrapper,并重写getParameter()方法;
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对象;
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进行测试。
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