首页 > 编程知识 正文

filter怎么用(java filter 原理_干货,一文带你超详细了解 Filter 的原理及应用)

时间:2023-05-04 14:26:54 阅读:123346 作者:1981

提出问题

1、我们在进入后台很多页面的时候都需要登录。 只有登录的用户才能看到这些页面。 我们每次请求都需要检查用户是否登录。 这很麻烦。 有没有办法在我们要求之前帮我做这些事? 有!

2、我们的网络APP经常接收中文字符。 因为可能会导致中文乱码,所以我们每次都需要在方法的开头使用request.setcharacterencoding (“utf-8”)。 我们要获取参数值,可以直接自己设置代码吗? 我能行!

这个问题的解决方法我们想出了一个方法。 那就是,我们每次要求都拦截它,当我们安装好一切东西时,就放弃要求。 类似于我们地铁站的检票系统。 每个人进站的时候都必须刷卡。 取钱后才能坐车。

web上也有这个机制,我们叫它过滤器。 是我们接下来要学习的掩体

过滤器介绍

什么是菲尔

1 )过滤器(Filter )过滤器的基本功能是阻止servlet容器调用servlet (JSP )的过程,从而在servlet处理请求之前和servlet响应请求之后提供特殊功能。

2 ) servlet API为开发人员创建Filter程序定义了三个接口类。 是过滤器、过滤器通道和过滤器配置

3 ) Filter程序是实现Filter接口的Java类,它与servlet程序一样由servlet容器调用和执行

4 ) Filter程序必须在web.xml文件中注册,并设置可以侦听的资源。 过滤器程序可以侦听Jsp、servlet、静止图像文件和静止html文件

过滤器的工作原理是什么

这个servlet过滤器就是我们的过滤器

1 )如果web.xml包含用于阻止servlet的Filter,则此Filter是Tomcat和servlet通信线路上的级别。 此过滤器可以侦听从servlet容器发送到servlet的请求,以及servlet返回到servlet容器的响应,确定是否将请求传递给servlet,以及是否更改请求和相应的信息

2 )可以在一个web APP应用程序中注册多个Filter程序,每个Filter程序可以侦听一个或一系列servlet。

3 )如果多个Filter程序拦截了某个servlet的访问进程,则当访问该servlet的请求到达时,web容器会将这些Filter程序合并到一个Filter链(过滤器链)中过滤器链中每个过滤器的拦截顺序与在APP应用程序的web.xml中映射的顺序匹配

过滤器-故障诊断

赫尔洛-世界

过滤器创建三个步骤。

1、创建过滤器实现类,实现过滤器接口

2、创建web.xml配置文件,配置过滤器信息

3、运行项目后,可以看到过滤器在发挥作用

代码:

//1,过滤器实现类

publicclassmyfirstfilterimplementsfilter {

@ overridepublicvoidinit (filterconfigfilterconfig ) throwsServletException {

System.out.println (初始化方法);

}

@ overridepublicvoiddofilter (servletrequestrequest,ServletResponse response,FilterChain chain ) throwsIOException,servle

system.out.println(dofilter方法);

}

@ override公共语音目录(

System.out.println ('销毁方法. ';

}

//2,web.xml配置

我的第一过滤器

com.atguigu.filter.my first filter

我的第一过滤器

/index.jsp

//3,运行程序后,index.jsp页面不再显示,后台输出“dofilter方法”,表示我们写的filter已运行。

过滤器的生命周期

1 )服务器启动时,filter创建并初始化,init )方法执行。

2 )请求通过filter时执行doFilter方法。

3)服务器停止时,调用 destroy 方法。

filter放行请求

我们发现,刚才的 filter 配置好后,index.jsp 页面没法访问了,访问这个页面的时候 filter的 dofilter 方法被调用了。说明 dofilter 这个方法拦截了我们的请求。

我们如何显示页面呢。也就是如何将请求放行呢。我们观察发现有个 filterChain 被传入到这个方法里面了。filterChain 里面有个 doFilter()方法。放行请求只需要调用 filterChain 的 dofilter 方法。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throwsIOException,ServletException {

System.out.println("dofilter方法");

chain.doFilter(request, response);//放行请求

}

filter拦截原理

我们在 chain.doFilter(request, response);方法后也写一句话,System.out.println

(“doFilter 方法执行后…”),在 index.jsp 页面也写上 jsp 脚本片段,输出我是 jsp 页面。运行程序发现控制台输出了这几句话:

dofilter 方法… 我是 jsp 页面

dofilter 方法后…

我们不难发现 filter 的运行流程

FilterChain

doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

在 doFilter 执行之前,由容器将 filterChain 对象传入方法。调用此对象的.doFilter()方法可以将请求放行,实际上是执行过滤器链中的下一个 doFilter 方法,但是如果只有一个过滤器,则为放行。

FilterConfig

FilterConfig 类似 ServletConfig,是 filter 的配置信息对象。FilterConfig 对象具有以下方法。

getFilterName():获取当前 filter 的名字。获取的是在 web.xml 中配置的 filter-name 的值

getInitParameter(String name):获取 filter 的初始化参数。在 web.xml 中配置

getInitParameterNames():获取 filter 初始化参数名的集合。

getServletContext():获取当前 web 工程的 ServletContext 对象。

Filter的 url-pattern

url-pattern 是配置 filter 过滤哪些请求的。主要有以下几种配置:

web.xml 中配置的/都是以当前项目路径为根路径的

1)精确匹配:

/index.jsp/user/login 会在请求/index.jsp、/user/login 的时候执行过滤方法

2)路径匹配:

/user/* /* 凡是路径为/user/下的所有请求都会被拦截,/*表示拦截系统的所有请求,包括静态资源文件。

3)扩展匹配:

*.jsp *.action 凡是后缀名为.jsp .action 的请求都会被拦截。

注意:/login/*.jsp 这种写法是错误的,只能是上述三种的任意一种形式。不能组合新形式。

*jsp 也是错误的,扩展匹配必须是后缀名

4)多重 url-pattern 配置

上面的三种形式比较有局限性,但是 url-pattern 可以配置多个,这样这三种组合基本就能解决所有问题了

多 Filter执行顺序

如果同一个资源有多个 filter 都对其拦截,则拦截的顺序是按照 web.xml 中配置的顺序进行的

执行流程图如下

请求总是在处理之后再回来执行 doFilter 之后的方法。

HttpServletWrapper 和 HttpServletResponseWrapper

定义

Servlet API 中提供了一个 HttpServletRequestWrapper 类来包装原始的 request 对象,HttpServletRequestWrapper 类实现了 HttpServletRequest 接口中的所有方法, 这些方法的内部实现都是仅仅调用了一下所包装的的 request 对象的对应方法

//包装类实现 ServletRequest 接口.

public class ServletRequestWrapper implementsServletRequest {//被包装的那个 ServletRequest 对象

privateServletRequest request;//构造器传入 ServletRequest 实现类对象

publicServletRequestWrapper(ServletRequest request) {if (request == null) {throw new IllegalArgumentException("Request cannot be null");

}this.request =request;

}//具体实现 ServletRequest 的方法: 调用被包装的那个成员变量的方法实现。

publicObject getAttribute(String name) {return this.request.getAttribute(name);

}publicEnumeration getAttributeNames() {return this.request.getAttributeNames();

}//...

}

相类似 Servlet API 也提供了一个 HttpServletResponseWrapper 类来包装原始的 response 对象

作用

用于对 HttpServletRequest 或 HttpServletResponse 的某一个方法进行修改或增强.

public class MyHttpServletRequest extendsHttpServletRequestWrapper{publicMyHttpServletRequest(HttpServletRequest request) {super(request);

}

@OverridepublicString getParameter(String name) {

String val= super.getParameter(name);if(val != null && val.contains(" fuck ")){

val= val.replace("fuck", "****");

}returnval;

}

}

使用

在 Filter 中, 利用 MyHttpServletRequest 替换传入的 HttpServletRequest

HttpServletRequest req = newMyHttpServletRequest(request);

filterChain.doFilter(req, response);

此时到达目标 Servlet 或 JSP 的 HttpServletRequest 实际上是 MyHttpServletRequest

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。