Filter,过滤器,顾名思义,即是对数据等的过滤,预处理过程。为什么要引入过滤器呢?在平常访问网站的时候,有时候发一些敏感的信息,发出后显示时 就会将敏感信息用*等字符替代,这就是用过滤器对信息进行了处理。这只是一个简单的例子,当然,过滤器那么强大,它的功能也不可能局限于此,它不仅能预处 理数据,只要是发送过来的请求它都是可以预处理的,同时,它还可以对服务器返回的响应进行预处理,这样,大大减轻了服务器的压力。例如,实现URL级别的 权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。下面来详细介绍一下过滤器。

一、定义

  学习一个东西,我们首先要理解它的定义。

1.概念

   过滤作用,对从客户端向服务器端发送的请求进行过滤,也可以对服务器端返回的响应进行处理。它使用户可以改变一个request和修改一个 response.。Filter 不是一个servlet,它不能产生一个response,但是它能够在一个request到达servlet之前预处理request,也可以在 response离开servlet时处理response。换句话说,filter其实是客户端与servlet中间的一个传递者,并且它可以对要传递 的东西进行修改。

  注意:过滤器是用来拦截请求和响应的,不能产生响应,而servlet是用来处理请求并产生响应的。

2.适用场合

  实现URL级别的权限访问控制,过滤敏感词汇,压缩响应信息等。

3.过滤器如何实现拦截

  • 当客户端发生请求后,在HttpServletRequest 到达Servlet 之前,过滤器拦截客户的HttpServletRequest 。
  • 根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。
  • 在过滤器中调用doFilter方法,对请求放行。请求到达Servlet后,对请求进行处理并产生HttpServletResponse发送给客户端。
  • 在HttpServletResponse 到达客户端之前,过滤器拦截HttpServletResponse 。
  • 根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。
  • 最后,HttpServletResponse到达客户端。

4.Filter接口

  Servlet API提供了一个Filter接口,编写的过滤器必须实现该接口。

5.Filter的生命周期

(1)Filter接口中有三个重要的方法。

  • init()方法:初始化参数,在创建Filter时自动调用。当我们需要设置初始化参数的时候,可以写到该方法中。
  • doFilter()方法:拦截到要执行的请求时,doFilter就会执行。这里面写我们对请求和响应的预处理。
  • destroy()方法:在销毁Filter时自动调用。

(2)Filter的生命周期

    Filter的创建和销毁由web服务器控制。

  • 服务器启动的时候,web服务器创建Filter的实例对象,并调用其init方法,完成对象的初始化功能。filter对象只会创建一次,init方法也只会执行一次。
  • 拦截到请求时,执行doFilter方法。可以执行多次。
  • 服务器关闭时,web服务器销毁Filter的实例对象。

6.Filter对象——FilterConfig

  用 户在配置filter时,可以使用<init-param>为filter配置一些初始化参数,当web容器实例化Filter对象,调用其 init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过 filterConfig对象的方法,就可获得:

  • String getFilterName():得到filter的名称。
  • String getInitParameter(String name): 返回在部署描述中指定名称的初始化参数的值。如果不存在返回null.
  • Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。
  • public ServletContext getServletContext():返回Servlet上下文对象的引用。

7.过滤器链——FilterChain

  一组过滤器对某些web资源进行拦截,那么这组过滤器就称为过滤器链。过滤器的执行顺序和<filter-mapping>有关(谁在前先执行谁)。

二、开发步骤

  了解了过滤器的相关概念,接下来进行实例开发。

1.编写步骤

  • 编写java类实现Filter接口,并实现其doFilter方法。
  • 在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。

2.示例

(1)简单的Filter示例

  • 编写FilterDemo1类
 1 package com.oracle.filter;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11
12 public class FilterDemo1 implements Filter{
13
14 /*
15 * 对Filter的整个生命周期了解的一个案例
16 * 注意事项:
17 * 1.实现Filter接口时导入的是javax.servlet.Filter包
18 * 2.方法均有web服务器自动调用,不需我们手动调用
19 * 3.init方法中一般写初始化参数,这里先不用,后面的例子再使用。
20 * 4.destroy方法一般不需要写任何代码
21 * 5.重写doFilter方法,可以写我们对拦截的请求和响应的处理动作。
22 * 6.写完该类后配置filter,在web.xml中配置。
23 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
24 */
25 @Override
26 public void init(FilterConfig filterConfig) throws ServletException {
27 // TODO Auto-generated method stub
28 System.out.println("FilterDemo1的init方法被调用");
29 }
30
31 @Override
32 public void doFilter(ServletRequest request, ServletResponse response,
33 FilterChain chain) throws IOException, ServletException {
34 // TODO Auto-generated method stub
35 System.out.println("我是FilterDemo1,客户端向Servlet发送的请求被我拦截到了");
36 chain.doFilter(request, response);
37 System.out.println("我是FilterDemo1,Servlet向客户端发送的响应被我拦截到了");
38 }
39
40 @Override
41 public void destroy() {
42 // TODO Auto-generated method stub
43 System.out.println("FilterDemo1的destroy方法被调用");
44 }
45
46 }
  • 配置filter,在web.xml文件中加入下面这段代码
1 <filter>
2 <filter-name>filterDemo1</filter-name>
3 <filter-class>com.oracle.filter.FilterDemo1</filter-class>
4 </filter>
5 <filter-mapping>
6 <filter-name>filterDemo1</filter-name>
7 <url-pattern>/*</url-pattern>
8 <!-- /*是对所有的文件进行拦截 -->
9 </filter-mapping>
  • 控制台结果

  • 分 析:从上面结果可以看出,在服务器启动时,就调用了init方法,当访问页面时,该过滤器拦截到请求执行doFilter方法,在该方法中,使用 doFilter方法,当返回响应后,继续执行剩下的代码,执行完成后将响应传给客户端。当关闭服务器时,服务器就调用了destroy方法。

(2)Filter链示例

  • 编写FilterDemo1类
 1 package com.oracle.filter;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11
12 public class FilterDemo1 implements Filter{
13
14 /*
15 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
16 */
17 @Override
18 public void init(FilterConfig filterConfig) throws ServletException {
19 // TODO Auto-generated method stub
20 }
21
22 @Override
23 public void doFilter(ServletRequest request, ServletResponse response,
24 FilterChain chain) throws IOException, ServletException {
25 // TODO Auto-generated method stub
26 System.out.println("我是FilterDemo1,客户端向Servlet发送的请求被我拦截到了");
27 //对请求放行,进入下一个过滤器FilterDemo2
28 chain.doFilter(request, response);
29 System.out.println("我是FilterDemo1,Servlet向客户端发送的响应被我拦截到了");
30 }
31
32 @Override
33 public void destroy() {
34 // TODO Auto-generated method stub
35 }
36
37 }
  • 编写FilterDemo2类
 1 package com.oracle.filter;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11
12 public class FilterDemo2 implements Filter{
13
14 @Override
15 public void init(FilterConfig filterConfig) throws ServletException {
16 // TODO Auto-generated method stub
17
18 }
19
20 @Override
21 public void doFilter(ServletRequest request, ServletResponse response,
22 FilterChain chain) throws IOException, ServletException {
23 // TODO Auto-generated method stub
24 System.out.println("我是FilterDemo2,客户端向Servlet发送的请求被我拦截到了");
25 //对请求放行,进入Servlet
26 chain.doFilter(request, response);
27 System.out.println("我是FilterDemo2,Servlet向客户端发送的响应被我拦截到了");
28 }
29
30 @Override
31 public void destroy() {
32 // TODO Auto-generated method stub
33
34 }
35
36 }
  • 配置filter,在web.xml文件中加入下面这段代码
 1 <filter>
2 <filter-name>filterDemo1</filter-name>
3 <filter-class>com.oracle.filter.FilterDemo1</filter-class>
4 </filter>
5 <filter>
6 <filter-name>filterDemo2</filter-name>
7 <filter-class>com.oracle.filter.FilterDemo2</filter-class>
8 </filter>
9
10 <filter-mapping>
11 <filter-name>filterDemo1</filter-name>
12 <url-pattern>/*</url-pattern>
13 <!-- /*是对所有的文件进行拦截 -->
14 </filter-mapping>
15 <filter-mapping>
16 <filter-name>filterDemo2</filter-name>
17 <url-pattern>/*</url-pattern>
18 <!-- /*是对所有的文件进行拦截 -->
19 </filter-mapping>
  • 控制台结果

  • 分 析:当有多个过滤器对同一个请求进行拦截时,根据web.xml文件中<filter-mapping>的配置顺序,谁在前,先执行谁。当第 一过滤器拦截成功后,会执行doFilter方法,该方法中,调用chain.doFilter方法,会将该请求放行给下一个过滤器,依次执行,直到执行 到最后一个过滤器,当最后一个过滤器调用chain.doFilter方法时,请求会被放行给Servlet,当Servlet处理返回响应信息时,先返 回到最后执行的过滤器,继续执行该过滤器剩下的代码。依次返回,直到返回到第一个过滤器,最后返回给客户端。

 (3)禁用所有动态页面的缓存过滤器

  • 编写FilterDemo3类
 1 package com.oracle.filter;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletResponse;
12
13 public class FilterDemo3 implements Filter{
14
15 @Override
16 public void init(FilterConfig filterConfig) throws ServletException {
17 // TODO Auto-generated method stub
18
19 }
20
21 @Override
22 public void doFilter(ServletRequest request, ServletResponse response,
23 FilterChain chain) throws IOException, ServletException {
24 // 在response的头部设置Cache-Control、Pragma和Expires即可取消缓存
25 HttpServletResponse resp = (HttpServletResponse)response;
26 resp.setHeader("Cache-Control", "no-cache");
27 resp.setHeader("Pragma", "no-cache");
28 resp.setDateHeader("Expires", -1);
29 chain.doFilter(request, resp);
30 }
31
32 @Override
33 public void destroy() {
34 // TODO Auto-generated method stub
35
36 }
37
38 }
  • 配置filter,在web.xml文件中加入下面这段代码
1 <filter>
2 <filter-name>filterDemo3</filter-name>
3 <filter-class>com.oracle.filter.FilterDemo3</filter-class>
4 </filter>
5
6 <filter-mapping>
7 <filter-name>filterDemo3</filter-name>
8 <url-pattern>/*</url-pattern>
9 </filter-mapping>

(4) 分IP统计网站的访问次数过滤器

  • 编写FilterDemo4类
 1 package com.oracle.filter;
2
3 import java.io.IOException;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import javax.servlet.Filter;
8 import javax.servlet.FilterChain;
9 import javax.servlet.FilterConfig;
10 import javax.servlet.ServletContext;
11 import javax.servlet.ServletException;
12 import javax.servlet.ServletRequest;
13 import javax.servlet.ServletResponse;
14
15 public class FilterDemo4 implements Filter{
16
17 private FilterConfig filterConfig;
18 @Override
19 public void init(FilterConfig filterConfig) throws ServletException {
20 // TODO Auto-generated method stub
21
22 //初始化参数,ipCount用来存放ip及访问次数
23 ServletContext application = filterConfig.getServletContext();
24 Map<String,Integer> ipCount = new HashMap<String,Integer>();
25 application.setAttribute("ipCount",ipCount);
26 this.filterConfig = filterConfig;
27 }
28
29
30 @Override
31 public void doFilter(ServletRequest request, ServletResponse response,
32 FilterChain chain) throws IOException, ServletException {
33 // TODO Auto-generated method stub
34 ServletContext application = filterConfig.getServletContext();
35 Map<String,Integer> ipCount = (HashMap<String,Integer>)application.getAttribute("ipCount");
36 String ip = request.getRemoteAddr();
37 Integer count = ipCount.get(ip);
38 if(count != null){
39 //Map中存在该ip
40 count = count + 1;
41 }else{
42 count = 1;
43 }
44 ipCount.put(ip, count);
45 application.setAttribute("ipCount",ipCount);
46 chain.doFilter(request, response);
47 }
48
49 @Override
50 public void destroy() {
51 // TODO Auto-generated method stub
52
53 }
54
55 }
  • 编写index.jsp页面
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
3 <%
4 String path = request.getContextPath();
5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
6 %>
7
8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
9 <html>
10 <head>
11 <base href="<%=basePath%>">
12
13 <title>My JSP 'index.jsp' starting page</title>
14 <meta http-equiv="pragma" content="no-cache">
15 <meta http-equiv="cache-control" content="no-cache">
16 <meta http-equiv="expires" content="0">
17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
18 <meta http-equiv="description" content="This is my page">
19 <!--
20 <link rel="stylesheet" type="text/css" href="styles.css">
21 -->
22 </head>
23
24 <body>
25 <h1>分IP统计网站浏览次数</h1>
26 <table border="1" width="400">
27 <tr>
28 <th>IP地址</th>
29 <th>浏览次数</th>
30 </tr>
31 <c:forEach items="${ipCount}" var="m">
32 <tr>
33 <td>${m.key}</td>
34 <td>${m.value}</td>
35 </tr>
36 </c:forEach>
37 </table>
38 </body>
39 </html>
  • 配置filter,在web.xml文件中加入下面这段代码
1 <filter>
2 <filter-name>filterDemo4</filter-name>
3 <filter-class>com.oracle.filter.FilterDemo4</filter-class>
4 </filter>
5
6 <filter-mapping>
7 <filter-name>filterDemo4</filter-name>
8 <url-pattern>/*</url-pattern>
9 </filter-mapping>
  • 网页结果

(5)自动登录

  • 编写AutoLoginFilter类
 1 package com.oracle.filter;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.Cookie;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpSession;
14
15 import com.oracle.biz.UserInfoBiz;
16 import com.oracle.biz.impl.UserInfoBizImpl;
17 import com.oracle.entity.UserInfo;
18 import com.oracle.util.CookieUtil;
19
20 public class AutoLoginFilter implements Filter{
21
22 @Override
23 public void init(FilterConfig filterConfig) throws ServletException {
24 // TODO Auto-generated method stub
25
26 }
27
28 @Override
29 public void doFilter(ServletRequest request, ServletResponse response,
30 FilterChain chain) throws IOException, ServletException {
31 // TODO Auto-generated method stub
32 //先判断session中是否存在,存在则放行,不存在则判断cookie中是否存在用户名密码,存在则到数据库中查询是否正确,正确则存入session并放行,不正确则放行
33 HttpServletRequest req = (HttpServletRequest)request;
34 HttpSession session = req.getSession();
35 UserInfo user = (UserInfo)session.getAttribute("user");
36 if(user != null){
37 chain.doFilter(req, response);
38 }else{
39 //session中不存在用户
40 Cookie[] cookies = req.getCookies();
41 Cookie cookie = CookieUtil.findCookie(cookies, "autoLogin");
42 if(cookie!=null){
43 //在cookie中找到该用户
44 UserInfoBiz ubiz = new UserInfoBizImpl();
45 String name = cookie.getValue().split("#oracle#")[0];
46 String pwd = cookie.getValue().split("#oracle#")[1];
47 String msg = ubiz.login(name, pwd);
48 if("登陆成功!".equals(msg)){
49 user = ubiz.getByName(name);
50 session.setAttribute("user", user);
51 chain.doFilter(req, response);
52 }else{
53 chain.doFilter(req, response);
54 }
55 }else{
56 //没有找到该客户
57 chain.doFilter(req, response);
58 }
59 }
60 }
61
62 @Override
63 public void destroy() {
64 // TODO Auto-generated method stub
65
66 }
67
68
69 }
  • 编写DoLoginServlet
 1 package com.oracle.servlet;
2
3 import java.io.IOException;
4
5 import javax.servlet.ServletException;
6 import javax.servlet.http.Cookie;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10 import javax.servlet.http.HttpSession;
11
12 import com.oracle.biz.UserInfoBiz;
13 import com.oracle.biz.impl.UserInfoBizImpl;
14 import com.oracle.entity.UserInfo;
15
16 public class DoLoginServlet extends HttpServlet {
17
18 /**
19 * Constructor of the object.
20 */
21 public DoLoginServlet() {
22 super();
23 }
24
25 /**
26 * Destruction of the servlet. <br>
27 */
28 public void destroy() {
29 super.destroy(); // Just puts "destroy" string in log
30 // Put your code here
31 }
32
33 /**
34 * The doGet method of the servlet. <br>
35 *
36 * This method is called when a form has its tag value method equals to get.
37 *
38 * @param request the request send by the client to the server
39 * @param response the response send by the server to the client
40 * @throws ServletException if an error occurred
41 * @throws IOException if an error occurred
42 */
43 public void doGet(HttpServletRequest request, HttpServletResponse response)
44 throws ServletException, IOException {
45
46 doPost(request,response);
47 }
48
49 /**
50 * The doPost method of the servlet. <br>
51 *
52 * This method is called when a form has its tag value method equals to post.
53 *
54 * @param request the request send by the client to the server
55 * @param response the response send by the server to the client
56 * @throws ServletException if an error occurred
57 * @throws IOException if an error occurred
58 */
59 public void doPost(HttpServletRequest request, HttpServletResponse response)
60 throws ServletException, IOException {
61
62 HttpSession session = request.getSession();
63 request.setCharacterEncoding("UTF-8");
64 response.setCharacterEncoding("UTF-8");
65 String name = request.getParameter("myname");
66 String pwd = request.getParameter("pwd");
67 String autoLogin = request.getParameter("autoLogin");
68 UserInfoBiz ubiz = new UserInfoBizImpl();
69 //ubiz.login(name, pwd):判断用户是否登陆成功,返回一个字符串。成功则返回"登陆成功!",不成功则返回对应的错误提示。
70 String msg = ubiz.login(name, pwd);
71 if("登陆成功!".equals(msg)){
72 UserInfo user = ubiz.getByName(name);
73 session.setAttribute("user", user);
74 if("true".equals(autoLogin)){
75 //利用cookie记住用户名和密码
76 Cookie cookie = new Cookie("autoLogin",user.getUserName()+"#oracle#"+user.getPassword());
77 //设置有效时间
78 cookie.setMaxAge(60*60*24);
79 //将cookie回写到浏览器
80 response.addCookie(cookie);
81 }
82 response.sendRedirect("success.jsp");
83 }else{
84 request.setAttribute("msg", msg);
85 request.getRequestDispatcher("login.jsp").forward(request, response);
86 }
87 }
88
89 /**
90 * Initialization of the servlet. <br>
91 *
92 * @throws ServletException if an error occurs
93 */
94 public void init() throws ServletException {
95 // Put your code here
96 }
97
98 }
  • 编写CookieUtil
 1 package com.oracle.util;
2
3 import javax.servlet.http.Cookie;
4
5
6
7 public class CookieUtil {
8
9 public static Cookie findCookie(Cookie[] cookies,String name){
10 if(cookies==null){
11 return null;
12 }else{
13 for(Cookie cookie:cookies){
14 if(cookie.getName().equals(name)){
15 return cookie;
16 }
17 }
18 return null;
19 }
20 }
21 }
  • 编写login.jsp
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%
3 String path = request.getContextPath();
4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
5 %>
6
7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
8 <html>
9 <head>
10 <base href="<%=basePath%>">
11
12 <title>My JSP 'login.jsp' starting page</title>
13
14 <meta http-equiv="pragma" content="no-cache">
15 <meta http-equiv="cache-control" content="no-cache">
16 <meta http-equiv="expires" content="0">
17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
18 <meta http-equiv="description" content="This is my page">
19 <!--
20 <link rel="stylesheet" type="text/css" href="styles.css">
21 -->
22
23 </head>
24
25 <body>
26 <form action="doLogin" method="post">
27 用户名<input name="myname"><br/>
28 密&nbsp;码<input type="password" name="pwd"><br/>
29 <input type="checkBox" name="autoLogin" value="true">自动登录<br/>
30 <input type="submit" value="登陆">
31 </form>
32 </body>
33 </html>
  • 编写success.jsp
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
3 <%
4 String path = request.getContextPath();
5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
6 %>
7
8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
9 <html>
10 <head>
11 <base href="<%=basePath%>">
12
13 <title>My JSP 'success.jsp' starting page</title>
14
15 <meta http-equiv="pragma" content="no-cache">
16 <meta http-equiv="cache-control" content="no-cache">
17 <meta http-equiv="expires" content="0">
18 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
19 <meta http-equiv="description" content="This is my page">
20 <!--
21 <link rel="stylesheet" type="text/css" href="styles.css">
22 -->
23
24 </head>
25
26 <body>
27 <c:if test="${empty user}">
28 <h2>您还未登陆,请去<a href="login.jsp">登陆</a></h2>
29 </c:if>
30 <c:if test="${not empty user}">
31 <h2>欢迎你${user.userName}</h2>
32 </c:if>
33 </body>
34 </html>
  • 配置filter和servlet,在web.xml文件中加入下面的代码
 1 <servlet>
2 <description>This is the description of my J2EE component</description>
3 <display-name>This is the display name of my J2EE component</display-name>
4 <servlet-name>DoLoginServlet</servlet-name>
5 <servlet-class>com.oracle.servlet.DoLoginServlet</servlet-class>
6 </servlet>
7
8 <servlet-mapping>
9 <servlet-name>DoLoginServlet</servlet-name>
10 <url-pattern>/doLogin</url-pattern>
11 </servlet-mapping>
12
13 <filter>
14 <filter-name>AutoLoginFilter</filter-name>
15 <filter-class>com.oracle.filter.AutoLoginFilter</filter-class>
16 </filter>
17 <filter-mapping>
18 <filter-name>AutoLoginFilter</filter-name>
19 <url-pattern>/*</url-pattern>
20 </filter-mapping>

(6)处理网站的Get和Post请求乱码

  • 思 路:增强request对象的getParameter方法等方法。编写一个类MyHttpServletRequest实现 HttpServletRequestWrapper,重写它的getParameter方法等方法,在这些方法中对不同方式提交的数据进行转码。在过滤 器中,将request强制转换成MyHttpServletRequest类型的对象,这样,当再次使用getParameter等方法时其实调用的是 你重写后的getParametr方法,也就是已经处理过的数据,这样就不用再担心乱码的问题了。
  • MyHttpServletRequest类
 1 package com.oracle.bookshop.filter;
2
3 import java.io.UnsupportedEncodingException;
4 import java.util.Map;
5
6 import javax.servlet.http.HttpServletRequest;
7 import javax.servlet.http.HttpServletRequestWrapper;
8
9
10 public class MyHttpServletRequest extends HttpServletRequestWrapper {
11 /*
12 * 该类重写
13 */
14 private HttpServletRequest request;
15
16 private boolean hasEncode;
17
18 public MyHttpServletRequest(HttpServletRequest request) {
19 super(request);// super必须写
20 this.request = request;
21 }
22
23 // 对需要增强方法进行覆盖
24 @Override
25 public Map getParameterMap() {
26 // 先获得请求方式
27 String method = request.getMethod();
28 if (method.equalsIgnoreCase("post")) {
29 // post请求
30 try {
31 // 处理post乱码
32 request.setCharacterEncoding("utf-8");
33 return request.getParameterMap();
34 } catch (UnsupportedEncodingException e) {
35 e.printStackTrace();
36 }
37 } else if (method.equalsIgnoreCase("get")) {
38 // get请求
39 Map<String, String[]> parameterMap = request.getParameterMap();
40 if (!hasEncode) { // 确保get手动编码逻辑只运行一次
41 for (String parameterName : parameterMap.keySet()) {
42 String[] values = parameterMap.get(parameterName);
43 if (values != null) {
44 for (int i = 0; i < values.length; i++) {
45 try {
46 // 处理get乱码
47 values[i] = new String(values[i]
48 .getBytes("ISO-8859-1"), "utf-8");
49 } catch (UnsupportedEncodingException e) {
50 e.printStackTrace();
51 }
52 }
53 }
54 }
55 hasEncode = true;
56 }
57 return parameterMap;
58 }
59
60 return super.getParameterMap();
61 }
62
63 @Override
64 public String getParameter(String name) {
65 Map<String, String[]> parameterMap = getParameterMap();
66 String[] values = parameterMap.get(name);
67 if (values == null) {
68 return null;
69 }
70 return values[0]; // 取回参数的第一个值
71 }
72
73 @Override
74 public String[] getParameterValues(String name) {
75 Map<String, String[]> parameterMap = getParameterMap();
76 String[] values = parameterMap.get(name);
77 return values;
78 }
79
80 }
  • 编写CharacterEnodingFilter
 1 package com.oracle.bookshop.filter;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletRequest;
12
13 public class CharacterEnodingFilter implements Filter{
14
15 @Override
16 public void destroy() {
17 // TODO Auto-generated method stub
18
19 }
20
21 @Override
22 public void doFilter(ServletRequest request, ServletResponse response,
23 FilterChain chain) throws IOException, ServletException {
24 // TODO Auto-generated method stub
25 HttpServletRequest req = (HttpServletRequest)request;
26 MyHttpServletRequest myreq = new MyHttpServletRequest(req);
27 chain.doFilter(myreq, response);
28
29 }
30
31 @Override
32 public void init(FilterConfig arg0) throws ServletException {
33 // TODO Auto-generated method stub
34
35 }
36
37
38 }

Servlet之Filter详细讲解的更多相关文章

  1. Android webservice的用法详细讲解

    Android webservice的用法详细讲解 看到有很多朋友对WebService还不是很了解,在此就详细的讲讲WebService,争取说得明白吧.此文章采用的项目是我毕业设计的webserv ...

  2. servlet的filter的使用

    一.概述 过滤器是servlet的一个重要特性,它提供一种机制,允许在过滤器中,即可以修改浏览器的请求信息,也可以对服务器处理后的响应信息进行修改. 一个过滤器是一个实现了Filter接口的java类 ...

  3. Servlet和Filter的url匹配以及url-pattern详解 及 filter 循环问题的解决

    Servlet和filter是J2EE开发中常用的技术,使用方便,配置简单,老少皆宜.估计大多数朋友都是直接配置用,也没有关心过具体的细节,今天遇到一个问题,上网查了servlet的规范才发现,ser ...

  4. introduce of servlet and filter

    servlet简介: Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中 ...

  5. Java Servlet (1) —— Filter过滤请求与响应

    Java Servlet (1) -- Filter过滤请求与响应 版本: Java EE 6 参考来源: Oracle:The Java EE 6 Tutorial: Filtering Reque ...

  6. servlet,listener,filter,interceptor的关系

    1.servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层.最早支持 Servlet 技术 ...

  7. Siki_Unity_2-1_API常用方法和类详细讲解(下)

    Unity 2-1 API常用方法和类详细讲解(下) 任务101&102:射线检测 射线origin + direction:射线检测:射线是否碰撞到物体 (物体需要有碰撞器),碰撞物体的信息 ...

  8. Servlet和Filter的url匹配以及url-pattern详解

    Servlet和filter是J2EE开发中常用的技术,使用方便,配置简单,老少皆宜.估计大多数朋友都是直接配置用,也没有关心过具体的细节,今天遇到一个问题,上网查了servlet的规范才发现,ser ...

  9. Iframe 用法的详细讲解

    1转自:https://blog.csdn.net/judyge/article/details/51786064 zIframe 用法的详细讲解 把iframe解释成“浏览器中的浏览器“很是恰当 & ...

随机推荐

  1. usb驱动开发11之设备生命线

    暂时先告别媒人,我们去分析各自的生命旅程,最后还会回到usb_device_match函数. 首先当你将usb设备连接在hub的某个端口上,hub检测到有设备连接了进来,它会为设备分配一个struct ...

  2. Linux 网络编程一(TCP/IP协议)

    以前我们讲过进程间通信,通过进程间通信可以实现同一台计算机上不同的进程之间通信. 通过网络编程可以实现在网络中的各个计算机之间的通信. 进程能够使用套接字实现和其他进程或者其他计算机通信. 同样的套接 ...

  3. 用 eric6 与 PyQt5 实现python的极速GUI编程(系列02)---- 省市县(区)下拉列表多级联动

    [概览] 本文实现如下的程序: 主要步骤如下: 1.在eric6中新建项目,新建窗体 2.(自动打开)进入PyQt5 Desinger,编辑图形界面,保存 3.回到eric 6,对上一步得到的界面文件 ...

  4. CSS 动画之十-图片+图片信息展示

    这个动画主要是运用了一些css3的特性,效果是展示一张商品图片,然后在商品图片的制定位置显示该商品的详细信息.效果在chrome浏览器中预览. <!DOCTYPE html> <ht ...

  5. python数字图像处理(11):图像自动阈值分割

    图像阈值分割是一种广泛应用的分割技术,利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值,以确定图像中每个像素 ...

  6. [CareerCup] 3.2 Min Stack 最小栈

    3.2 How would you design a stack which, in addition to push and pop, also has a function min which r ...

  7. c# 技巧之 泛型方法

    泛型 指的是编译时不需要指定具体的参数类型,可以在运行时动态地赋予某一种数据类型的机制.  相信很多人对泛型类并不陌生,像Dictionary,List等结构都属于泛型类.有趣的是,一个函数/方法也可 ...

  8. JavaScript中的各种小坑汇总

    1.Number()将部分非数字类型转换为0 强制转换为数值类型函数: parseFloat.parseInt 优点:对非数值类型统一返回NaN 缺点:会将一部分符合数值类型的字符串也识别为数值 pa ...

  9. Web API 基于ASP.NET Identity的Basic Authentication

    今天给大家分享在Web API下,如何利用ASP.NET Identity实现基本认证(Basic Authentication),在博客园子搜索了一圈Web API的基本认证,基本都是做的Forms ...

  10. 第四章 一切从IL开始

    从这一部分开始,就开始讲.net的本质了,这第四章就是讲有关IL(中间语言)的内容,主要利用工具,看看VS到底编译出来的是什么东西,从中我们可以看到实现的方式和过程.有助于我们更好的了解.net的本质 ...