java servlet过滤器简解及实例

article/2025/10/15 5:00:24

     在整个概念中,个人觉得有一篇文章写得不错,通俗易懂,这里就直接套用以上原博文,

 


一、概念:

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

Java Web 之过滤器Filter详解

二、Filter简介

        Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。

三、快速入门

1、新建一个类,实现Filter接口

2、实现doFilter()方法,打印一句话,来证明能够进行拦截

3、在web.xml中进行配置(参照Servlet配置)

4、访问一个页面,看看能不能拦截

[java]  view plain copy
  1. package com.test.filter;    
  2.   
  3.      
  4.   
  5. import java.io.IOException;    
  6.   
  7. import javax.servlet.Filter;    
  8.   
  9. import javax.servlet.FilterChain;    
  10.   
  11. import javax.servlet.FilterConfig;    
  12.   
  13. import javax.servlet.ServletException;    
  14.   
  15. import javax.servlet.ServletRequest;    
  16.   
  17. import javax.servlet.ServletResponse;    
  18.   
  19. public class Demo1Filter implements Filter {    
  20.   
  21.     private FilterConfig filterConfig;    
  22.   
  23.      
  24.   
  25.     public void doFilter(ServletRequest request, ServletResponse response,    
  26.   
  27.             FilterChain chain) throws IOException, ServletException {    
  28.   
  29.         System.out.println("Demo1过滤前");    
  30.   
  31.         System.out.println(filterConfig.getInitParameter("param1"));    
  32.   
  33.         chain.doFilter(request, response);//放行。让其走到下个链或目标资源中    
  34.   
  35.         System.out.println("Demo1过滤后");    
  36.   
  37.     }    
  38.   
  39.      
  40.   
  41.     public void init(FilterConfig filterConfig) throws ServletException {    
  42.   
  43.         System.out.println("初始化了");    
  44.   
  45.         this.filterConfig = filterConfig;    
  46.   
  47.     }    
  48.   
  49.      
  50.   
  51.     public void destroy() {    
  52.   
  53.         System.out.println("销毁了");    
  54.   
  55.     }    
  56.   
  57. }   


web.xml中进行配置

[html]  view plain copy
  1. <filter>  
  2.     <filter-name>Demo1Filter</filter-name>  
  3.     <filter-class>com.itheima.filter.Demo1Filter</filter-class>  
  4.     <init-param>  
  5.         <param-name>param1</param-name>  
  6.         <param-value>value在这里呢</param-value>  
  7.     </init-param>  
  8. </filter>  
  9. <filter-mapping>  
  10.     <filter-name>Demo1Filter</filter-name>  
  11.     <url-pattern>/*</url-pattern>  
  12.     <dispatcher>REQUEST</dispatcher> <!-- 没有配置dispatcher就是默认request方式的 -->  
  13.     <dispatcher>FORWARD</dispatcher>  
  14.     <dispatcher>ERROR</dispatcher>  
  15.     <dispatcher>INCLUDE</dispatcher>  
  16. </filter-mapping>  


 

四、Filter的应用场景

通过对filter过滤器的了解,可以得知在以下三种情况下可以做些处理:

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

比如,可以在用户权限验证等等。判断用户是否有访问某些资源的权限,有权限放行,没权限不执行chain.doFilter方法。

2> 通过在调用chain.doFilter方法之前,做些处理来达到某些目的。

比如,解决中文乱码的问题等等。可以在doFilter方法前,执行设置请求编码与响应的编码。甚至可以对request接口进行封装装饰来处理get请求方式的中文乱码问题(重写相应的request.getParameter方法)

3> 通过在调用chain.doFilter方法之后,做些处理来达到某些目的。

比如对整个web网站进行压缩。在调用chain.doFilter方法之前用类Aresponse对象进行封装装饰,重写getOutputStream和重写getWriter方法。在类A内部中,将输出内容缓存进ByteArrayOutputStream流中,然后在chain.doFilter方法执行后,获取类AByteArrayOutputStream流缓存数据,用GZIPOutputStream流进行压缩下。

五、Filter实现拦截的原理

Filter接口中有一个doFilter方法,当开发人员编写好Filter类实现doFilter方法,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前(服务器内部对资源的访问机制决定的),都会先调用一下filterdoFilter方法

六、Filter生命周期

Servlet一样Filter的创建和销毁也是由WEB服务器负责。不过与Servlet区别的是,它是1>在应用启动的时候就进行装载Filter(Servletload-on-startup配置效果相同)2>容器创建好Filter对象实例后,调用init()方法。接着被Web容器保存进应用级的集合容器中去了等待着,用户访问资源。3>当用户访问的资源正好被Filterurl-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法(Filter对象常驻留Web容器了)4>应用服务被停止或重新装载了,则会执行Filterdestroy方法,Filter对象销毁。

注意:init方法与destroy方法只会直接一次。

七、Filter部署应用注意事项

1> filter-mapping标签中servlet-nameurl-pattern

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

2> filter-mapping标签中dispatcher

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

REQUEST

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

INCLUDE

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

FORWARD

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

ERROR

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


总结:

一个filter 包括:

  1. 在servlet被调用之前截获;

  2. 在servlet被调用之前检查servlet request;

  3. 根据需要修改request头和request数据;

  4. 根据需要修改response头和response数据;

  5. 在servlet被调用之后截获.

  你能够配置一个filter 到一个或多个servlet;单个servlet或servlet组能够被多个filter 使用.几个实用的filter 包括:用户辨认filter,日志filter,审核filter,加密filter,符号filter,能改变xml内容的XSLT filter等.



====================================割割割======================

以上为文章原文,此处尊重原作者附上出处:http://blog.csdn.net/jzhf2012/article/details/8476997


表示自己一直处于仅仅只会用的级别,而不懂得原理不懂得由来,所以此处也只能是需要使用的代码块进行自我复习.

filter作用及原理上面其实已经讲得差不多(要我写还写不出来这么高大上的东西),那么我附上一个简单而实用的代码,

<!-- 自定义的过滤器  --><filter><filter-name>authorityFilter</filter-name>  <span style="font-family: Arial, Helvetica, sans-serif;">			</span>
<filter-class>cn.thinknet.filter.AuthorityFilter</filter-class><span style="font-family: Arial, Helvetica, sans-serif;"><!-- 自定义过滤器的位置 --></span>
<init-param><param-name>allowAuthorityURL</param-name><!-- 不需要过滤的地址 --><param-value>login.jsp,register.jsp,login.action,sendMail.action,register.action,getbackPwdOne.jsp,getbackPwdTwo.jsp,getbackPwdThree.jsp,getbackOne.action,getbackTwo.action,getbackThree.action,forget_pwd.action,getHomePageResult.action,index.jsp,index.html,userAuthen.action</param-value></init-param><init-param><param-name>authorityURL</param-name><!-- 只对指定过滤参数后缀进行过滤 --><param-value>.action,.jsp,.do</param-value></init-param><init-param><param-name>redirectPath</param-name><!-- 未通过跳转到登录界面 --><param-value>/wrtPlatformVt/wrt/login.jsp</param-value></init-param><init-param><param-name>disableFilter</param-name><!-- Y:过滤无效 --><param-value>N</param-value></init-param></filter><filter-mapping> <!-- 拦截所有的请求信息   如想通过扩展名匹配拦截。 如:.action后缀的请求 配置则为 *.action--><!-- 精确匹配  顾名思义精确到单个请求  如:/manage/login.action 配置则为/manage/login.action --><!-- 路劲匹配  通过*配符的方式进行相对匹配,如下的/* 则表示拦截所有信息 --><filter-name>authorityFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

附上:servlet url-pattern匹配规则: http://zy19982004.iteye.com/blog/1751695


<init-param> 标签对应的是参数名和值,可以用于在init()时通过FilterConfig的对象 filterConfig.getInitParameter("参数名")获取。

附上:<init-param>标签的基本使用:http://blog.csdn.net/yakson/article/details/9203231


自定义过滤器代码:

package cn.thinknet.filter;import java.io.IOException;
import java.io.PrintWriter;
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.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;import cn.thinknet.utils.others.AKKeysUtil;/*** 过滤器* * * */
public class AuthorityFilter extends HttpServlet implements Filter
{/*** */private static final long serialVersionUID = 4504557649329493897L;public String[] allowAuthorityURLs;public String[] authorityURLs;public FilterConfig config;/*** 过滤不能访问的地址*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain filterChain) throws IOException, ServletException{// 未登录需要跳转的地址String redirectPath = config.getInitParameter(AKKeysUtil.WEB_CONTEXT_REDIRECT_PATH);// 过滤是否启用boolean isEnable = true; // 过滤器可用String disableStr = config.getInitParameter(AKKeysUtil.WEB_CONTEXT_DISABLE_FILTER);if (StringUtils.isNotEmpty(disableStr)){isEnable = disableStr.equals("N");}HttpServletRequest req = (HttpServletRequest) request;// 判断过滤器是否启用if (!isEnable){filterChain.doFilter(request, response);return;}// 需要过滤的后缀String authorityURL = config.getInitParameter(AKKeysUtil.WEB_CONTEXT_AUTHORITY_URL);if (StringUtils.isNotEmpty(authorityURL)){authorityURLs = authorityURL.split(",");}// 判断当前的请求地址中是否存在需要过滤的后缀if (authorityURL(req)){// 不需要过滤的地址String allowAuthorityURL = config.getInitParameter(AKKeysUtil.WEB_CONTEXT_ALLOW_AUTHORITY_URL);if (StringUtils.isNotEmpty(allowAuthorityURL)){allowAuthorityURLs = allowAuthorityURL.split(",");}// 过滤不拦截的urlif (allowAuthorityURL(req)){filterChain.doFilter(request, response);return;} else{// 判断当前用户是否登录,没有登录直接跳转到登录页面if (!relogin(redirectPath, response, req)){return;}}// 最后对action与jsp进行权限校验// if (authorityRequestAddress(req))// {// 【暂时不实现纵向越权控制】filterChain.doFilter(request, response);// }// else// {// 没有权限时// noAuthority();// }} else{// 例如js,image,css等文件不列入权限控制范围内filterChain.doFilter(request, response);}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException{config = filterConfig;// WebApplicationContext ctx = WebApplicationContextUtils// .getWebApplicationContext(this.getServletContext());// menuService = (MenuService) ctx.getBean("menuService");}/*** 在未登陆的情况下允许访问的URL* * @return Boolean*/private boolean allowAuthorityURL(HttpServletRequest request){boolean isAllow = false;// 获得当前访问的地址String current_url = request.getRequestURI();if (ArrayUtils.isNotEmpty(allowAuthorityURLs)){for (String allowUrl : allowAuthorityURLs){if (StringUtils.containsIgnoreCase(current_url, allowUrl)){isAllow = true;break;}}}return isAllow;}/*** 需要过滤的后缀* * @return Boolean*/private boolean authorityURL(HttpServletRequest request){boolean isFilter = false;if (ArrayUtils.isNotEmpty(authorityURLs)){for (String suffix : authorityURLs){if (request.getRequestURI().indexOf(suffix) != -1){isFilter = true;break;}}}return isFilter;}/*** 判断员工回话是否失效* * @param redirectPath*            需要跳转的页面* @param response*            请求响应* * @param request*            请求* * @throws IOException* * @return boolean 假:代表重新登录,真:代表session存在*/private boolean relogin(String redirectPath, ServletResponse response,HttpServletRequest request) throws IOException{response.setContentType("text/html;charset=UTF-8");response.setCharacterEncoding("UTF-8");PrintWriter out = response.getWriter();// 判断该用户是否存在session中,如果有直接进入当前actionif (null == request.getSession(true).getAttribute(AKKeysUtil.USER_EMPLOY_SESSION_KEY)){// 跳转到登录界面out.print("<script language='javascript'>alert('身份验证失效,请重新登录!');window.parent.location.href='"+ redirectPath + "';</script>");return false;}// 如果用户禁用掉cookie,则跳转到登录界面,提示用户启用cookieCookie[] cookies = request.getCookies();if (null == cookies){// 1.可能用户清除过cookie 2.可能是由于用户禁用了cookie 此时都会跳转到登录界面// 跳转到登录界面out.print("<script language='javascript'>alert('Cookie被清理或是已禁用,请尝试重新登录!');window.parent.location.href='"+ redirectPath + "';</script>");return false;}return true;}
}

注意,AKKeysUtil这个是封装好的一个工具类,所有使用到的地方对应的均是 <init-param>标签的参数名,自行对应更改即可。


以上过滤器经测试是可用的,不过由于源码并不是我所写(公司前辈所留),所以这里只能是拿出来分享之说,servlet过滤器并不等同于拦截器,常用的拦截器莫过于框架所自带的,如:Struts2,spring mvc等。  如想达到权限认证(是否登陆、未登录返回登陆页面),通过框架的拦截器达到其效果,当然也可以直接使用servlet的filter,毕竟我就是直接使用它的。。。




http://chatgpt.dhexx.cn/article/DURCjiKq.shtml

相关文章

Servlet过滤器案例-自动登录

使用过滤器实现自动登录 登录的jsp页面 <% page language"java" import"java.util.*" pageEncoding"UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head> <title&g…

Servlet过滤器拦截器

文章目录 1、什么是Servlet&#xff1f;2、过滤器与拦截器的区别 1、什么是Servlet&#xff1f; 参考&#xff1a;https://blog.csdn.net/wozaibohaibian/article/details/124778494 ​ servlet就是一个组件,需要符合servlet规范,并且需要部署到servlet容器里面才能运行 注&…

servlet过滤器原理及使用

原理 首先了解什么是过滤器&#xff0c;各种文章已经写的很清楚了 引用来自这篇大牛的博客 是Servlet技术中最激动人心的技术&#xff0c;WEB开发人员通过Filter技术&#xff0c;对web服务器管理的所有web资源&#xff1a;例如Jsp, Servlet, 静态图片文件或静态 html 文件等进…

Servlet——过滤器

Servlet过滤器 什么是过滤器 过滤器是一个程序&#xff0c;它先于与之相关的Servlet页面运行在服务器上&#xff0c;但它并不是一个标准的Servlet&#xff0c;它不能处理用户请求&#xff0c;也不能对客户端生成响应。它主要用于对HttpServletRequest进行预处理&#xff0c;也…

servlet过滤器的简单使用

为什么要用过滤器或者拦截器&#xff1f; 简单来讲&#xff0c;当一个账户需要进入某个系统调用某个接口时&#xff0c;我们需要对其进行相应验证&#xff0c;否则一旦接口暴露&#xff0c;可能会造成系统崩溃。这个时候我们就需要用拦截器对调用接口一方进行身份验证。 serv…

Servlet过滤器Filter

Servlet Filter 又称 Servlet 过滤器&#xff0c;它是在 Servlet 2.3 规范中定义的&#xff0c;能够对 Servlet 容器传给 Web 资源的 request 对象和 response 对象进行检查和修改。Filter 不是 Servlet&#xff0c;不能直接访问&#xff0c;它本身也不能生成 request 对象和 r…

Servlet之过滤器

问题引入 以往的Servlet中&#xff0c;有冗余代码&#xff0c;多个servlet都要进行编写 概念 过滤器(Filter)是处于客户端于服务器资源之间的一道技术。 图示&#xff1a; 过滤器的作用 执行地位在Servlet之前&#xff0c;客户端发送请求时&#xff0c;会先经过Filter&#xff…

servlet过滤器的介绍

servlet过滤器是服务器与客户端请求与响应的中间层组件&#xff0c;它主要是用于对浏览器的请求进行过滤处理&#xff0c;并将过滤后的请求再转给下一个资源。 servlet过滤器的基本概念 Servlet过滤器从字面上的字意理解为经过一层次的过滤处理才达到使用的要求&#xff0c;而…

Servlet——过滤器(fiter)

什么是过滤器&#xff1f; 过滤器是Servlet的一个组件&#xff0c;是设计模式中过滤器模式&#xff08;又叫责任链模式&#xff09;的一种经典实现 是Servlet技术中最激动人心的技术&#xff0c;WEB开发人员通过Filter技术&#xff0c;对web服务器管理的所有web资源&#xff…

java基础篇---Servlet过滤器

Servlet过滤器从字面上的字意理解为景观一层次的过滤处理才达到使用的要求&#xff0c;而其实Servlet过滤器就是服务器与客户端请求与响应的中间层组件&#xff0c;在实际项目开发中Servlet过滤器主要用于对浏览器的请求进行过滤处理&#xff0c;将过滤后的请求再转给下一个资源…

mac下idea卡顿问题解决

一、背景 mac下idea卡顿 二、原因 赋予idea的内存太小了&#xff0c;需要给他更大的内存 三、解决方法 1、修改idea.vmoptions 配置文件。 help --Edit Custom VM Options 2、修改文件 这是我修改之前的&#xff1a; -Xms128m -Xmx750m -XX:ReservedCodeCacheSize512m…

macOS看视频卡顿如何修复

很多时候我们都会遇到这样一个问题&#xff1a;明明电脑很新&#xff0c;处理器内存什么的也都不差&#xff0c;但看在线视频就是卡&#xff0c;画面和音频对不上&#xff0c;令人很难受。其实这是Flash播放器开了P2P的原因。今天我就教教大家macOS看视频卡顿如何修复。 先打开…

MAC 外接键盘卡顿处理

系统偏好设置-> 键盘。 1&#xff1a;将『按键重复』调到快&#xff0c;将『重复前延迟』调到段&#xff0c;点击『更改键盘类型』,并且按照提示一步步让电脑识别键盘。 2 &#xff1a;切换『文本』&#xff0c;去勾『触控栏键入建议』&#xff0c;可以起到调优作用。

MAC如何解决idea卡顿问题

故事是这样的 我的mac配置也不是很高&#xff0c;内存大概是这样的 但是刚下载完idea后&#xff0c;简直比我之前2000块的windows本都卡。偶买噶&#xff0c;差点想直接退货。 好在控制住脾气&#xff0c;然后冷静思考后觉得&#xff0c;不该呀&#xff0c;好歹那么贵&#x…

matlab java mac_Matlab for mac卡顿、抛Java异常

在苹果上使用Matlab后&#xff0c;试用了几个版本后都十分卡顿&#xff0c;后来抛出了Java.lang.OutOfMemoryError. 后查阅资料认为可能是Matlab JVM内存不够的问题。官方给出的解决方案如下&#xff0c;将JVM内存设置到最大后&#xff0c;情况有所缓解。有时候仍然有些卡 但是…

解决 Macbook 连接蓝牙鼠标卡顿问题

作者&#xff1a;吴业亮 博客&#xff1a;wuyeliang.blog.csdn.net 2.4Ghz的蓝牙与2.4Ghz的Wi-Fi起冲突&#xff0c;环境干扰大。会造成蓝牙鼠标卡顿具体解决办法如下&#xff1a; 打开“系统偏好设置”——“网络”&#xff0c;然后选择更多这里&#xff08;如图&#xff09…

优化不必要的动画,以减少Mac卡顿

本文通过两种方式来减少Mac的动画&#xff0c;友情提示&#xff1b;常重启有助于保持Mac系统正常运转。 条件允许的情况下&#xff0c;安装旧版本Mac系统、减少运行不必要的软件能优化Mac运行速度。 一、系统设置 打开系统偏好设置——>辅助功能 勾选 “减弱动态效果” …

终极方案——解决MacBook/Mac mini连接无线鼠标卡顿、漂移

终极方案——解决MacBook/Mac mini连接无线鼠标卡顿、漂移 Intel处理器机器/旧版Mac系统Apple M系列新机器 Intel处理器机器/旧版Mac系统 找到如图设置&#xff0c;修改网络首选项顺序 Apple M系列新机器 1、在系统设置里新建一个管理员用户 2、在访达-前往-电脑-磁盘-找到新建…

m1 MacBook Pro pycharm打字卡顿问题解决

一般m1芯片的MacBook Pro在pycharm中打字卡顿无非两种情况导致的&#xff0c;一种是分配给pycharm编辑器的内存太小&#xff1b;另一种是下载的版本与m1芯片版本不一致&#xff0c;不兼容导致的卡顿&#xff0c;下面文章详细记录了解决这两种情况的方法。 一、内存不足导致的卡…

Macbook Pro 鼠标卡顿问题

Macbook Pro 鼠标卡顿问题 目前无解&#xff0c;只能改善。该问题最早能追溯到 2015年。 https://jingyan.baidu.com/article/ff42efa93632c5c19e220208.html 原因 据说是无线频段冲突。 罗技低于400 的鼠标就别看了&#xff0c;白花钱。 鼠标在 macbook pro 的卡顿现象主要表现…