本文引自:https://www.cnblogs.com/dudududu/p/8505177.html

参考博客:http://www.cnblogs.com/coderland/p/5902878.html

https://www.cnblogs.com/HigginCui/p/5772514.html

基本概念在参考博客中,已经讲的很清楚了。这里,简单总结一下,并贴一个完整实例。

总结:

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

2)Filter技术主要进行对用户请求的预处理,也可以对服务器响应进行后处理。

这两种情况都属于直接访问页面(也包括直接访问Servlet),故在配置<filter-mapping>时,可以不写<dispatcher>,使用默认的REQUEST。(也可以写出来直接指定为REQUEST)

一般地,客户端提交请求信息通过HttpServletRequest到达Servlet,然后Servlet进行处理并产生响应,响应通过HttpServletResponse传递到客户端。

Filter在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest,根据需要检查HttpServletRequest,或者修改HttpServletRequest 头和数据,称为对用户请求的预处理。

Filer在HttpServletResponse从Servlet到达客户端之前,拦截HttpServletResponse ,根据需要检查HttpServletResponse,或者修改HttpServletResponse头和数据,称为对服务器响应进行后处理。

3)Filer的生命周期:

实例化(web.xml)——>初始化(init()方法)——>过滤(doFilter()方法)——>销毁(destroy()方法)

    public void init(FilterConfig filterConfig) throws ServletException;//初始化//filter对象只会创建一次,init方法也只会执行一次和我们编写的Servlet程序一样,Filter的创建和销毁由WEB容器负责。 web 应用程序启动时,web 容器读取web.xml配置文件,将创建Filter 的实例对象,并调用其init方法(这个init方法中可以读取web.xml文件中过滤器的参数)完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作。开发人员可以通过init方法的参数FilterConfig对象,获得当前filter配置信息。public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求//可执行n次这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候执行该方法。FilterChain参数的doFilter方法用于访问后续过滤器或者调用目标资源。public void destroy();//销毁//该方法在Filter的生命周期中仅执行一次。Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前被调用。在这个方法中,可以释放过滤器使用的资源。

4)Filter开发步骤:

  (1)编写java类实现javax.servlet.Filter接口,并实现其doFilter方法;

  (2)在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源。

5)Filter链:

  在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。

  web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

6)FilterConfig接口:

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

7)在检查URI路径中的是否含有某个初始值,对于servlet来说,是指配置servlet时指定的url-pattern的值,而不是servlet类名。

8)在实现Filter的类中的doFilter()方法中,需要将传进来的ServletRequest转换为HttpServletRequest,将传进来的ServletResponse转换为HttpServletResponse,才能进行相关方法的调用。

9)过滤器的分类: 

  (1)REQUEST:当用户直接访问页面(包括用户请求的预处理和对服务器响应进行后处理)时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。 
  (2)INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
  (3)FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
  (4)ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

贴个例子,实现两个过滤器一个判断用户是否登录然后跳转指定页面,一个用来处理乱码问题:

login.jsp:

<form action="doLogin" method="post">
用户名:<input type="text" name="userName"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
<input type="reset" value="重置"/>
</form>

创建一个success.jsp用于展示跳转成功。

创建登录跳转Servlet:

package com.servlet;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;@SuppressWarnings("serial")
public class DoLoginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String userName=req.getParameter("userName");String password=req.getParameter("password");System.out.println(userName);if("张三".equals(userName)&&"123".equals(password)){//校验通过HttpSession session = req.getSession();session.setAttribute("userName", userName);       //这里必须使用重定向,不能使用请求转发       //请求转发:request.getRequestDispatcher().forward()是属于FORWARD类型的过滤器,需要在配置过滤器时,写明FORWARD类型的<dispatcher>resp.sendRedirect("success.jsp");}else{resp.sendRedirect("login.jsp");}}
}

注意:

请求转发:即request.getRequestDispatcher().forward(),是一种服务器的行为,客户端只有一次请求,服务器端转发后会将请求对象保存,地址栏中的URL地址不会改变,得到响应后服务器端再将响应发给客户端;

请求重定向:即response.sendRedirect(),是一种客户端行文,从本质上讲等同于两次请求,前一次请求对象不会保存,地址栏的URL地址会改变。

请求转发与请求重定向的区别,参考博客:http://blog.csdn.net/u012877472/article/details/50804568

创建第一个过滤器(解决乱码):

package com.filter;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;
import javax.servlet.http.HttpServletRequest;public class SetEconding implements Filter {@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {HttpServletRequest req=(HttpServletRequest)arg0;//解决乱码问题req.setCharacterEncoding("UTF-8");//别忘了放行arg2.doFilter(arg0, arg1);}@Overridepublic void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stub}}

创建第二个过滤器(是否登录):

package com.filter;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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class LoginFilter implements Filter {
  //定义一个FilterConfig,用于传递出初始化方法init()中的FilterConfig对象private FilterConfig config=null;@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {HttpServletRequest req=(HttpServletRequest)arg0;HttpServletResponse resp=(HttpServletResponse)arg1;HttpSession session=req.getSession();//获取配置文件中配置的初始化参数,在这里是获取不过滤页面名单String initParam=config.getInitParameter("NotFilter");String[] notFilterPages=initParam.split(";");     //不过滤的页面直接调用FilterChain的doFilter()方法跳转到下个过滤器或者目标资源if(notFilterPages!=null){for(int i=0;i<notFilterPages.length;++i){//跳过字段为空和空字符串的情况if(notFilterPages[i]==null||"".equals(notFilterPages[i]))continue;//注意这里是URI路径中的是否含有某个初始值,对于servlet来说,是指配置servlet时指定的url-pattern的值,而不是servlet类名if(req.getRequestURI().indexOf(notFilterPages[i])!=-1){arg2.doFilter(arg0, arg1);return;}}}     //当登录成功(即session中存在“userName”的值),则跳转到下一个过滤器或者目标资源//只要未登录成功,所有的页面跳转请求(免除过滤的页面和servlet处理类除外)都将跳转到登录页面if(session.getAttribute("userName")!=null){arg2.doFilter(arg0, arg1);return;}else{resp.sendRedirect("login.jsp");return;}}@Overridepublic void init(FilterConfig arg0) throws ServletException {config=arg0;}}

web.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"><display-name>javaEE_filter</display-name><welcome-file-list><welcome-file>index.html</welcome-file></welcome-file-list><!-- 第1个过滤器 --><!-- 配置解决乱码过滤器 --><filter><filter-name>SetEcondingFilter</filter-name><filter-class>com.filter.SetEconding</filter-class></filter><!-- 配置解决乱码过滤器映射 --><filter-mapping><filter-name>SetEcondingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 第2个过滤器 --><!-- 配置登录过滤器 --><filter><filter-name>LoginFilter</filter-name><filter-class>com.filter.LoginFilter</filter-class><init-param><param-name>NotFilter</param-name><param-value>login;doLogin</param-value></init-param></filter><!-- 配置登录过滤器映射 --><filter-mapping><filter-name>LoginFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 配置处理登录的Servlet --><servlet><servlet-name>LoginServlet</servlet-name><servlet-class>com.servlet.DoLoginServlet</servlet-class></servlet><!-- 配置处理登录Servlet的映射 --><servlet-mapping><servlet-name>LoginServlet</servlet-name><url-pattern>/doLogin</url-pattern></servlet-mapping>
</web-app>

乱码问题的解决方案:


乱码问题的解决代码主要有两种即使用request对象的setCharacterEncoding()方法和String的构造器方法。

例:

req.setCharacterEncoding("UTF-8");

userName=new String(userName.getBytes("ISO-8859-1"),"UTF-8");

1)使用过滤器:

在本例中,为了说明过滤器的执行顺序,而定义了两个过滤器并在配置时将处理乱码的过滤器放在了靠前的位置,但是对于处理乱码的过滤器完全可以将代码

req.setCharacterEncoding("UTF-8");

放在判断是否登录的过滤器的doFilter方法体中(最好放在方法体靠前位置,以保证过滤时先进行代码乱码的过滤)。而无需创建第二个过滤器。

2)当然,也可以使用javaBean的方式解决代码乱码问题

转载于:https://www.cnblogs.com/x-jingxin/p/9796613.html

Java web--过滤器相关推荐

  1. java web 过滤器跟拦截器的区别和使用

    2019独角兽企业重金招聘Python工程师标准>>> 1.首先要明确什么是拦截器.什么是过滤器 1.1 什么是拦截器: 拦截器,在AOP(Aspect-Oriented Progr ...

  2. 重温java web过滤器filter

    点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 精彩内容 java实战练习项目教程 2018微服务资源springboot.s ...

  3. java web过滤器

    java过滤器(imooc学习) 定义:过滤器是一个服务器端的组件,它可以截取用户端的请求与响应信息,并对这些信息过滤. 工作原理 1.过滤器中web容器启动时就进行加载 2.过滤器存在于用户请求和w ...

  4. Java Web过滤器(Filter)

    过滤器(Filter) 过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理 通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理 ...

  5. java web 过滤器 拦截器 监听器_Java中的拦截器和过滤器,可不是同一个东西

    过滤器(Filter) 过滤器就如上面的水质过滤器一样,把管道中的水进行一遍过滤再使用.过滤器基于filter接口中的doFilter回调函数,主要的用途是设置字符集.控制权限.控制转向.做一些业务逻 ...

  6. java web三大组件之filter过滤器

    过滤器是java web中相当重要的组成成分,是JavaWeb三大组件之一,它与Servlet很相似.不过过滤器有以下三条特性: 过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servle ...

  7. java web 怎么用solr_使用web过滤器增加solr后台登录验证

    solr后台自带是没有登录功能的,默认访问地址是:http://localhost:8983/solr/#/(内置jetty运行). 要给sorl后台增加登录验证方法: 1.使用web服务器的登录验证 ...

  8. java web压缩过滤器_Java Web过滤器Filter(五)

    Filter概述 Filter意为滤镜或者过滤器,用于在Servlet之外对request或者response进行修改.Filter提出滤镜链的概念,一个FilterChain包括多外Filter.客 ...

  9. Java Web应用程序的反跨站点脚本(XSS)过滤器

    这是为Java Web应用程序编写的一个好简单的反跨站点脚本(XSS)过滤器. 它的主要作用是从请求参数中删除所有可疑字符串,然后将其返回给应用程序. 这是我以前关于该主题的帖子的改进. 您应该将其配 ...

  10. Java Web开发中,自定义过滤器被执行两次的原因分析及解决办法

    本文出处:http://blog.csdn.net/chaijunkun/article/details/7646338,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在 ...

最新文章

  1. python写文件无法换行的问题
  2. 剪切粘贴时总是上次的内容_【Procreate 迷你课堂】#4 三指快速拷贝及粘贴
  3. python 实例变量_Python的类变量和实例变量详解
  4. c语言删除s字符串中所有子串t,从串s中删除所有和串t相同的子串的算法
  5. 在机器学习分类中如何处理训练集中不平衡问题
  6. VC++动态链接库(DLL)编程深入浅出(zz)
  7. android 支付宝沙箱测试环境,Android支付宝沙箱环境使用教程
  8. 浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除
  9. C#LeetCode刷题之#874-模拟行走机器人​​​​​​​(Walking Robot Simulation)
  10. JS 框架 :后台系统完整的解决方案
  11. java反射 泛型类型_【译】9. Java反射——泛型
  12. Linux chmod 修改多个文件权限
  13. Android签名 (二) 制作签名文件
  14. 【翠花学Vue】每日打卡——vue打卡6
  15. php剪切透明圆,php把图片处理成圆形透明的图片,做圆形透明头像,圆形头像_编程资料分享...
  16. linux为用户指定资源大小,Linux_Linux系统下生成一个指定大小的文件,在装系统,因此在这里随便记 - phpStudy...
  17. 学习PHP中的iconv扩展相关函数
  18. matlab累加数组的前n行,有一组m行n列的数组,在matlab中如何编程,每三个数求一次平均数(行与列分别求)?...
  19. Python基础必掌握的Traceback回溯机制操作详解
  20. 热图(Heat Map)的绘制

热门文章

  1. ***检测(IDS)存在的问题及发展趋势
  2. cornerstone4.0下载安装
  3. php中的 server 2008,window_Windows Server 2008开发指南解析,  Windows Server 2008开发指南中 - phpStudy...
  4. python和json转换_python和json之间转化
  5. java 富文本 xss_Jsoup 防止富文本 XSS 攻击
  6. 【sklearn第二十一讲】矩阵分解问题
  7. 设置blender界面语言为中文以及字体大小设置之方法
  8. 知乎上的48条神回复,针针见血
  9. 容器与微服务持续交付
  10. Django 上下文处理器