首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaWeb(五)Filter过滤器

JavaWeb(五)Filter过滤器

作者头像
二十三年蝉
发布2018-02-28 11:45:01
1K0
发布2018-02-28 11:45:01
举报
文章被收录于专栏:闻道于事闻道于事

Filter过滤器

Fileter介绍

Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如图:

Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源(拦截url)进行拦截后,WEB服务器每次在调用web资源之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:

   调用目标资源之前,让一段代码执行

   是否调用目标资源(即是否让用户访问web资源)。

   web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

   调用目标资源之后,让一段代码执行

开发Fileter步骤

   Filter开发分为二个步骤:

  • 编写java类实现Filter接口,并实现(三个方法)其doFilter方法。(现在也可以直接在Eclipse中创建Filter,可以不设置web.xml)
  • 1 package com.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.annotation.WebFilter; 11 12 /** 13 * Servlet Filter implementation class FilterTest2 14 */ 15 @WebFilter("/FilterTest2")//可以直接在此设置属性,不配置xml 16 public class FilterTest2 implements Filter { 17 18 public FilterTest2() { 19 // TODO Auto-generated constructor stub 20 } 21 22 public void destroy() { 23 // TODO Auto-generated method stub 24 } 25 26 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 27 28 chain.doFilter(request, response); 29 } 30 31 /** 32 * @see Filter#init(FilterConfig) 33 */ 34 public void init(FilterConfig fConfig) throws ServletException { 35 36 } 37 38 }
  • 在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。
  • 1 <filter> 2 <filter-name>TestFilTer1</filter-name> 3 <filter-class>com.filter.TestFilTer1</filter-class><!-- 完整的限定类名,可以直接在类名Ctrl点击复制 --> 4 </filter> 5 <filter-mapping> 6 <filter-name>TestFilTer1</filter-name> 7 <url-pattern>/*</url-pattern><!-- *代表所有 --> 8 </filter-mapping>

   Filter链 --- FilterChain

  • 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
  • web服务器根据Filter在web.xml文件中的注册顺序<mapping>,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

Filter的生命周期

init(FilterConfig filterConfig)throws ServletException:

和我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法进行初始化。需要注意的是:filter对象只会创建一次,init方法也只会执行一次。

  • 开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

doFilter(ServletRequest,ServletResponse,FilterChain)

  • 每次filter进行拦截都会执行
  • 在实际开发中方法中参数request和response通常转换为HttpServletRequestHttpServletResponse类型进行操作
1         HttpServletRequest request = (HttpServletRequest)req;
2         HttpServletResponse response = (HttpServletResponse)resp;

destroy():

  • 在Web容器卸载 Filter 对象之前被调用。

FilterConfig接口

l  用户在配置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上下文对象的引用。
  • Ø 注册

注册与映射Filter

<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径

  • <filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
  • <url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
  • <servlet-name>指定过滤器所拦截的Servlet名称。
  • <dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。
  • <dispatcher> 子元素可以设置的值及其意义:
  • REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
  • INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
  • FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
  • ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

<filter-mapping>

    <filter-name>testFilter</filter-name>

   <url-pattern>/index.jsp</url-pattern>

   <dispatcher>REQUEST</dispatcher>

   <dispatcher>FORWARD</dispatcher>

</filter-mapping>

Filter示例

过程:

web.xml中设置给index设置过滤

在过滤器中,获取session,为空也就是直接登访问index.jsp会跳转到登录页面

denglu.jsp,点击登录,跳转到chuli.jsp,设置session,在定向到index.jsp,获取到相应的session,通过进入

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
 3   <display-name>0826</display-name>
 4   <welcome-file-list>
 5     <welcome-file>index.html</welcome-file>
 6     <welcome-file>index.htm</welcome-file>
 7     <welcome-file>index.jsp</welcome-file>
 8     <welcome-file>default.html</welcome-file>
 9     <welcome-file>default.htm</welcome-file>
10     <welcome-file>default.jsp</welcome-file>
11   </welcome-file-list>
12   <filter>
13     <filter-name>TestFilTer1</filter-name>
14     <filter-class>com.filter.TestFilTer1</filter-class><!-- 包名,可以直接在类名Ctrl点击复制 -->
15   </filter>
16   <filter-mapping>
17     <filter-name>TestFilTer1</filter-name>
18     <url-pattern>/index.jsp</url-pattern><!-- 访问index.jsp会启动过滤 -->
19   </filter-mapping>
20 </web-app>
 1 package com.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.annotation.WebFilter;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 
14 /**
15  * Servlet Filter implementation class TestFilTer1
16  */
17 @WebFilter("/TestFilTer1")
18 public class TestFilTer1 implements Filter {
19 
20     /**
21      * Default constructor. 
22      */
23     public TestFilTer1() {
24         // TODO Auto-generated constructor stub
25     }
26 
27     /**
28      * @see Filter#destroy()
29      */
30     public void destroy() {
31         // TODO Auto-generated method stub
32         
33     }
34 
35     /**
36      * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
37      */
38     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
39         //先转型,可以使用转型后对象的方法
40         HttpServletRequest request = (HttpServletRequest)req;
41         HttpServletResponse response = (HttpServletResponse)resp;
42         //处理字符集
43         request.setCharacterEncoding("utf-8");
44         response.setCharacterEncoding("utf-8");
45         response.setContentType("text/html; charset=utf-8");
46         
47         Object obj = request.getSession().getAttribute("currentUser");//获取session对象
48         
49         if(obj == null) {
50             response.sendRedirect("denglu.jsp");
51         } else {
52             chain.doFilter(req, resp);
53         }
54     }
55 
56     /**
57      * @see Filter#init(FilterConfig)
58      */
59     public void init(FilterConfig fConfig) throws ServletException {
60         // TODO Auto-generated method stub
61     }
62 }
 1 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 2     pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10 <a href="chuli.jsp">登录</a>
11 
12 </body>
13 </html>
 1 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 2     pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10 <%
11 session.setAttribute("currentUser", "admin");
12 response.sendRedirect("index.jsp");
13 %>
14 </body>
15 </html>
 1 <%@ page language="java" contentType="text/html; charset=utf-8"
 2     pageEncoding="utf-8" import="java.util.ArrayList,com.util.User"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10 
11 当前
12 
13 </body>
14 </html>

例子2

设置部分页面过滤

过滤器:

 1 package com.hanqi.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 import javax.servlet.http.HttpServletResponse;
13 
14 public class SessionFilterTest implements Filter {
15     //设置成员变量,获取需要过滤的页面
16     private String pages;
17     
18     @Override
19     public void destroy() {
20         
21     }
22 
23     @Override
24     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
25             throws IOException, ServletException {
26         HttpServletRequest request = (HttpServletRequest)req;
27         HttpServletResponse response = (HttpServletResponse)resp;
28         
29         // 获取当前请求
30         String uri = request.getRequestURI();
31         System.out.println("当前发送的请求: "+uri);
32         
33         // 获取不需要判断session 的请求们
34         String[] _pages = pages.split(";");
35         
36         // 判断当前请求是否在不需要判断的请求里面
37         if(checkString(_pages, uri)) {
38             // 放行
39             chain.doFilter(req, resp);
40         } else {
41             // 先判断session再放行
42             Object obj = request.getSession().getAttribute("currentUser");
43             if(obj==null) {
44                 response.sendRedirect("login.jsp");
45             } else {
46                 chain.doFilter(req, resp);
47             }
48         }
49     }
50 
51     public static boolean checkString(String[] pages, String uri) {
52         for(String s : pages) {
53             if(uri.contains(s)) {//如果访问的地址包含了需要过滤的的页面
54                 return true;
55             }
56         }
57         return false;
58     }
59     
60     @Override
61     public void init(FilterConfig config) throws ServletException {
62         String str = config.getInitParameter("page");//获取当前参数,即需要过滤的页面
63         this.setPages(str);
64         System.out.println(str);
65     }
66 
67     public String getPages() {
68         return pages;
69     }
70 
71     public void setPages(String pages) {
72         this.pages = pages;
73     }
74 
75 }
 1 package com.hanqi.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 TestFilter implements Filter {
13 
14     @Override
15     public void destroy() {
16         // TODO Auto-generated method stub
17         
18     }
19 
20     @Override
21     public void doFilter(ServletRequest request, ServletResponse response, FilterChain arg2)
22             throws IOException, ServletException {
23         
24         request.setCharacterEncoding("utf-8");
25         response.setCharacterEncoding("utf-8");
26         response.setContentType("text/html; charset=utf-8");
27         
28         arg2.doFilter(request, response);
29     }
30 
31     @Override
32     public void init(FilterConfig arg0) throws ServletException {
33         // TODO Auto-generated method stub
34         
35     }
36 
37 }

web.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns="http://java.sun.com/xml/ns/javaee"
 4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 5     id="WebApp_ID" version="3.0">
 6     <filter>
 7         <filter-name>EncodingFilter</filter-name>
 8         <filter-class>com.hanqi.filter.TestFilter</filter-class>
 9     </filter>
10     <filter-mapping>
11         <filter-name>EncodingFilter</filter-name>
12         <url-pattern>/*</url-pattern>
13     </filter-mapping>
14     
15     <filter>
16         <filter-name>SessionFilter</filter-name>
17         <filter-class>com.hanqi.filter.SessionFilterTest</filter-class>
18         <init-param><!-- 设置可以放行的页面 -->
19             <param-name>page</param-name>
20             <param-value>login.jsp;LoginServlet;register.jsp;RegisterServlet</param-value>
21         </init-param>
22     </filter>
23     <filter-mapping>
24         <filter-name>SessionFilter</filter-name>
25         <url-pattern>/*</url-pattern>
26     </filter-mapping>
27 </web-app>

Servlet

 1 package com.hanqi.servlet;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.annotation.WebServlet;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 /**
11  * Servlet implementation class LoginServlet
12  */
13 @WebServlet("/LoginServlet")
14 public class LoginServlet extends HttpServlet {
15     private static final long serialVersionUID = 1L;
16        
17     /**
18      * @see HttpServlet#HttpServlet()
19      */
20     public LoginServlet() {
21         super();
22         // TODO Auto-generated constructor stub
23     }
24 
25     /**
26      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
27      */
28     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
29         String username = request.getParameter("username");
30         String password = request.getParameter("password");
31         System.out.println(username);
32         System.out.println(password);
33         //简单验证如果指定的用户名和密码相同,设置session
34         if("admin".equals(username)&&"12345".equals(password)) {
35             request.getSession().setAttribute("currentUser", "admin");
36             response.sendRedirect("index.jsp");
37         } else {
38             response.sendRedirect("fail.jsp");
39         }
40     }
41 
42     /**
43      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
44      */
45     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
46         // TODO Auto-generated method stub
47         doGet(request, response);
48     }
49 
50 }
 1 package com.hanqi.servlet;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.annotation.WebServlet;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 /**
11  * Servlet implementation class RegisterServlet
12  */
13 @WebServlet("/RegisterServlet")
14 public class RegisterServlet extends HttpServlet {
15     private static final long serialVersionUID = 1L;
16        
17     /**
18      * @see HttpServlet#HttpServlet()
19      */
20     public RegisterServlet() {
21         super();
22         // TODO Auto-generated constructor stub
23     }
24 
25     /**
26      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
27      */
28     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
29         String username = request.getParameter("username");
30         String password = request.getParameter("password");
31         String realname = request.getParameter("realname");
32         
33         System.out.println(username);
34         System.out.println(password);
35         System.out.println(realname);
36     }
37 
38     /**
39      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
40      */
41     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
42         // TODO Auto-generated method stub
43         doGet(request, response);
44     }
45 }

Jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>登录失败</h1>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="RegisterServlet" method="post">
    用户名: <input type="text" name="username" /><br>
    密码: <input type="text" name="password" /><br>
姓名: <input type="text" name="realname" /><br>
<input type="submit" value="注册" />
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

    <form action="LoginServlet" method="post">
        用户名: <input type="text" name="username" /><br> 密码: <input
            type="text" name="password" /><br> <input type="submit"
            value="登录" />
    </form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>首页</h1>
</body>
</html>

全站统一字符编码过滤器

1          request.setCharacterEncoding("utf-8");
2          response.setCharacterEncoding("utf-8");
3          response.setContentType("text/html; charset=utf-8");

禁用所有JSP页面缓存

因为动态页面数据,是由程序生成的,所以如果有缓存,就会发生,客户端查看数据不是最新数据情况 ,对于动态程序生成页面,设置浏览器端禁止缓存页面内容

1 response.setDateHeader("Expires",-1);
2 
3 response.setHeader("Cache-Control","no-cache");
4 
5 response.setHeader("Pragma","no-cache");

将禁用缓存代码,提起到过滤器中,通过url配置,禁用所有JSP页面的缓存

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-08-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Fileter介绍
    • 开发Fileter步骤
      • Filter的生命周期
        • FilterConfig接口
          • 注册与映射Filter
          • Filter示例
            • 全站统一字符编码过滤器
              • 禁用所有JSP页面缓存
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档