java过滤器Filter「建议收藏」

java过滤器Filter「建议收藏」一、简介Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断如是否有权限访问页面等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、…

大家好,又见面了,我是你们的朋友全栈君。

一、简介

Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断如是否有权限访问页面等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应 (Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的 web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁,以下通过代码示例来了解它 的使用。

二、实例

package test.filter; 
import ...; 
/**
 * 介绍过滤器的使用,以设置编码为例
 */
public class MyFilter implements Filter { 
  private FilterConfig config = null; 
  private boolean isFilter = false;
  
  public void destroy() { 
   System.out.println("MyFilter准备销毁..."); 
  } 
  
  public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { 
   // 强制类型转换 
   HttpServletRequest request = (HttpServletRequest)arg0; 
   HttpServletResponse response = (HttpServletResponse)arg1; 
   // 获取web.xm设置的编码集,设置到Request、Response 中   
   request.setCharacterEncoding(config.getInitParameter("charset"));   
   response.setContentType(config.getInitParameter("contentType"));   
   response.setCharacterEncoding(config.getInitParameter("charset"));   
   // 将请求转发到目的地继续执行
   chain.doFilter(request, response);
  } 
  
  public void init(FilterConfig arg0) throws ServletException { 
   this.config = arg0; 
   if(isFilter){
      System.out.println("MyFilter初始化..."); 
   }
  } 
  
  private void setIsFilter(boolean isFilter){
	this.isFilter = isFilter;
  }
}

然后在web. xml中配置该过滤器:

 <filter>
 	<filter-name>MyFilter</filter-name>
 	<filter-class>test.filter.MyFilter</filter-class>
 	<init-param>
 		<param-name>isFilter</param-name>
 		<param-value>true</param-value>
 	</init-param>
 </filter>
 <filter-mapping>
 	<filter-name>MyFilter</filter-name>
 	<url-pattern>/*</url-pattern>
 	<dispatcher>REQUEST</dispatcher> <!-- 没有配置dispatcher就是默认request方式的 -->
 	<dispatcher>FORWARD</dispatcher>
 	<dispatcher>ERROR</dispatcher>
 	<dispatcher>INCLUDE</dispatcher>
 </filt

三、详细介绍

在doFilter方法中通常都做些什么呢,下面列举一下:

1、通过控制对chain.doFilter的方法的调用,来决定是否需要访问目标资源。

比如,可以在用户权限验证等等。判断用户是否有访问某些资源的权限,有权限放行,没权限不执行chain.doFilter方法。
2、在调用chain.doFilter方法之前,做些处理来达到某些目的。
比如,解决中文乱码的问题等等。可以在doFilter方法前,执行设置请求编码与响应的编码。甚至可以对request接口进行封装装饰来处理get请求方式的中文乱码问题(重写相应的request.getParameter方法)。
3、在调用chain.doFilter方法之后,做些处理来达到某些目的。
比如对整个web网站进行压缩。在调用chain.doFilter方法之前用类A对response对象进行封装装饰,重写getOutputStream和重写getWriter方法。在类A内部中,将输出内容缓存进ByteArrayOutputStream流中,然后在chain.doFilter方法执行后,获取类A中ByteArrayOutputStream流缓存数据,用GZIPOutputStream流进行压缩下。

Filter不仅可以通过url-pattern来指定拦截哪些url匹配的资源。而且还可以通过servlet-name来指定拦截哪个指定的servlet(专门为某个servlet服务了,servlet-name对应Servlet的相关配置)。

filter-mapping标签中dispatcher指定过滤器所拦截的资源被Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。

REQUEST:

当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问或ERROR情况时,那么该过滤器就不会被调用。

INCLUDE:

如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

FORWARD:

如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

ERROR:

如若在A.jsp页面page指令中指定了error属性=examError.jsp,那么A.jsp中若出现了异常,会跳转到examError.jsp中处理。而在跳转到examError.jsp时,若过滤器配置了ERROR的dispather那么则会拦截,否则不会拦截。

四、高级配置(允许代理注入spring bean)

web.xml中配置过滤器DelegatingFilterProxy:

 

<filter>
    <filter-name>permission</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
 <filter-mapping>
    <filter-name>permission</filter-name>
    <url-pattern>*.htm</url-pattern>
</filter-mapping>

在spring bean配置中加入:

<bean id="permission" class="你的bean"></bean>

bean的id必须和filter-name一样。如果想不一样,可以这样配置:

<filter>
    <filter-name>permission</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
     <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>test</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>permission</filter-name>
    <url-pattern>*.htm</url-pattern>
</filter-mapping>

在spring bean配置中加入:

<bean id="test" class="你的bean"></bean>

以上你的spring bean必须实现Filter接口。

那这样子做是为了什么呢?

答:这样做就可以将DelegatingFilterProxy所代理的filter作为spring的bean,受到spring的管理,也就是通过Spring容器来管理filter的生命周期,还有就是如果filter中需要一些Spring容器的实例,可以通过spring直接注入,另外读取一些配置文件这些便利的操作都可以通过Spring来配置实现。

其中如果设置”targetFilterLifecycle”为True,则Filter.init()和Filter.destroy()有效;若为false,则这两个方法失效。

如果大家有用到shiro(一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理等)的话,通常就会用到这个DelegatingFilterProxy了!

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/133012.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 时间复杂度是什么_时间复杂度的表示方法

    时间复杂度是什么_时间复杂度的表示方法-宝宝为啥听不懂他们在讨论的时间复杂度0.0-我怎么知道这个算法运行得比那个算法快0.0-我究竟会不会超时0.0-我为什么还会超时0.0-时间复杂度怎么算0.0在别人还不会求时间复杂度的时候而你会了是不是很酷在别人都会求时间复杂度的时候而你不会是不是很尴尬千里之行始于足下希望这篇文章能祝你一臂之力=w= 此篇详解,希望能帮助各位稍微解决一下不解=w=…

    2025年6月6日
    2
  • postman接口自动化测试实战_apipost接口测试

    postman接口自动化测试实战_apipost接口测试Apifox介绍Apifox是API文档、API调试、APIMock、API自动化测试一体化协作平台,定位Postman+Swagger+Mock+JMeter。通过一套系

    2022年7月29日
    6
  • 0x0000007e_c0000005改兼容性没用

    0x0000007e_c0000005改兼容性没用对于怎么解决应用程序正常初始化0xc0000005失败这个问题,小编觉得是需要知道的,因为我们在生活中遇到类似这样的问题几率还是蛮大的。所以小伙伴们要接着往下看哟~接下来小编就来告诉你们怎么解决应用程序正常初始化0xc0000005失败的问题。有的时候刷网页刷到一半,就突然间出现应用程序正常初始化0xc0000005失败的窗口提示,但是这是怎么回事呢?又该怎么解决呢?稳住,接下来小编就来告诉你们怎…

    2022年10月3日
    2
  • Java面试宝典:42个面试题总结!

    Java面试宝典:42个面试题总结!本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力。下面的章节分为上下两篇,第一篇将要讨论面向对象编程和它的特点,关于Java和它的功能的常见问题,Java的集合类,垃圾收集器,第二篇主要讨论异常处理,Java小应用程序,Swing,JDBC,远程方法调用(RMI),Servlet和JSP。开始!目录面向对象编

    2022年7月7日
    20
  • idea2019激活码永久_在线激活

    (idea2019激活码永久)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月28日
    2.6K
  • RewriteRule指令[通俗易懂]

    RewriteRule指令[通俗易懂]作为RewriteRule指令的第三个参数。Flags是一个包含以逗号分隔的下列标记的列表: ‘last|L'(最后一个规则last)立即停止重写操作,并不再应用其他重写规则。它对应于Perl中的last命令或C语言中的break命令。这个标记可以阻止当前已被重写的URL为其后继的规则所重写。举例,使用它可以重写根路径的URL(‘/’)为实际存在的URL,比如,’/e/w

    2022年5月14日
    35

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号