100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Servlet 过滤器:Servlet Filter

Servlet 过滤器:Servlet Filter

时间:2021-07-22 01:45:08

相关推荐

Servlet 过滤器:Servlet Filter

目录

1、Filter 接口

2、Filter 的工作流程

3、Filter 的生命周期

4、注册与映射 Filter

5、示例

ServletFilter 又称 Servlet 过滤器,它是在 Servlet 2.3 规范中定义的,能够对 Servlet 容器传给 Web 资源的 request 对象和 response 对象进行检查和修改。

Filter 不是 Servlet,不能直接访问,它本身也不能生成 request 对象和 response 对象,它只能为 Web 资源提供以下过滤功能:

在 Web 资源被访问前,检查 request 对象,修改请求头和请求正文,或对请求进行预处理操作。将请求传递到下一个过滤器或目标资源。在 Web 资源被访问后,检查 response 对象,修改响应头和响应正文。

注意:过滤器并不是必须要将请求传递到下一个过滤器或目标资源,它可以自行对请求进行处理,并发送响应给客户端,也可以将请求转发或重定向到其他的 Web 资源。

Filter 是 Servlet 规范中最实用的技术,通过它可以对服务器管理的所有 Web 资源(例如 JSP、Servlet、静态 HTML 文件、静态图片等)进行拦截,从而实现一些特殊的功能,例如用户的权限控制、过滤敏感词、设置统一编码格式等。//Filter 是 Servlet 中比较核心的功能,与拦截器区分开来,拦截器不依赖于servlet容器,基于 java 反射机制实现

1、Filter 接口

与开发 Servlet 需要实现 javax.servlet.Servlet 接口类似,开发过滤器要实现 javax.servlet.Filter 接口,并提供一个公开的不带参的构造方法。在 Filter 接口中,定义了 3 个方法,如下表所示。

官方文档:Java EE 5 SDK

2、Filter 的工作流程

Filter的工作流程如下:

客户端请求访问容器内的Web 资源。Servlet 容器接收请求,并针对本次请求分别创建一个 request 对象和 response 对象。请求到达 Web 资源之前,先调用 Filter 的 doFilter() 方法,检查 request 对象,修改请求头和请求正文,或对请求进行预处理操作。在 Filter 的 doFilter() 方法内,调用 FilterChain.doFilter() 方法,将请求传递给下一个过滤器或目标资源。目标资源生成响应信息返回客户端之前,处理控制权会再次回到 Filter 的 doFilter() 方法,执行 FilterChain.doFilter() 后的语句,检查 response 对象,修改响应头和响应正文。响应信息返回客户端。

3、Filter 的生命周期

Filter 的生命周期分为 3 个阶段:

初始化阶段拦截和过滤阶段销毁阶段

初始化阶段

Servlet 容器负责加载和实例化 Filter。容器启动时,读取 web.xml 或 @WebFilter 的配置信息对所有的过滤器进行加载和实例化。

加载和实例化完成后,Servlet 容器调用 init() 方法初始化 Filter 实例。在 Filter 的生命周期内, init() 方法只执行一次。

拦截和过滤阶段

该阶段是 Filter 生命周期中最重要的阶段。当客户端请求访问 Web 资源时,Servlet 容器会根据 web.xml 或 @WebFilter 的过滤规则进行检查。当客户端请求的 URL 与过滤器映射匹配时,容器将该请求的 request 对象、response 对象以及 FilterChain 对象以参数的形式传递给 Filter 的 doFilter() 方法,并调用该方法对请求/响应进行拦截和过滤。

销毁阶段

Filter 对象创建后会驻留在内存中,直到容器关闭或应用被移除时销毁。销毁 Filter 对象之前,容器会先调用 destory() 方法,释放过滤器占用的资源。在 Filter 的生命周期内,destory() 只执行一次。

4、注册与映射 Filter

注册和映射 Filter 有 2 种方式:

通过 web.xml 配置通过 @WebFilter 注解配置

(1)通过web.xml配置

在 web.xml 中,通过 <filter> 及其子元素注册 Filter,代码如下。

<filter><filter-name>myFilter</filter-name><filter-class>swadian.servlet.filter.MyFilter</filter-class></filter><filter-mapping><filter-name>myFilter</filter-name><url-pattern>/FilterServlet</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping>

以上元素说明如下:

<filter-mapping> 元素用于设置 Filter 负责拦截的资源。<filter-name> 是<filter-mapping> 元素的子元素,用于设置 Filter 的注册名,该值必须在 <filter>元素的子元素 <filter-name> 中声明过。<url-pattern> 是<filter-mapping> 元素的子元素,用于设置 Filter 拦截的请求路径。<servlet-name> 是<filter-mapping> 元素的子元素,用于设置 Filter拦截的 Servlet 名称。<dispatcher> 是<filter-mapping> 元素的子元素,用于指定 Filter拦截的资源被 Servlet 容器调用的方式,可以是 REQUEST、INCLUDE、FORWARD 和 ERROR 之一,默认 REQUEST。用户可以设置多个 <dispatcher> 子元素指定 Filter 对资源的多种调用方式进行拦截。

<dispatcher> 元素的取值及其意义:

REQUEST:当用户直接访问页面时,容器将会调用过滤器。如果目标资源是通过 RequestDispatcher 的 include() 或 forward() 方法访问,则该过滤器就不会被调用。INCLUDE:如果目标资源通过 RequestDispatcher 的 include() 方法访问,则该过滤器将被调用。除此之外,该过滤器不会被调用。FORWARD:如果目标资源通过 RequestDispatcher 的 forward() 方法访问,则该过滤器将被调用,除此之外,该过滤器不会被调用。ERROR:如果目标资源通过声明式异常处理机制访问,则该过滤器将被调用。除此之外,过滤器不会被调用。

(2)使用 @WebFilter 注解进行配置

@WebFilter 注解也可以对过滤器进行配置,容器在部署应用时,会根据其具体属性配置将相应的类部署为过滤器。

@WebFilter 注解具有下表给出的一些常用属性。以下所有属性均为可选属性,但 value、urlPatterns、servletNames 三者必需至少包含一个,且 value 和 urlPatterns 不能共存,如果同时指定,通常忽略 value 的取值。

5、示例

创建名称为 MyFilter 的 Filter 类,代码如下。

package swadian.servlet.filter;import javax.servlet.DispatcherType;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.annotation.WebFilter;import java.io.IOException;@WebFilter(dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD,DispatcherType.INCLUDE,DispatcherType.ERROR},urlPatterns = {"/FilterServlet"})public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//设置向页面输出的格式与编码servletResponse.setContentType("text/html;charset=UTF-8");//执行目标方法filterChain.doFilter(servletRequest, servletResponse);//通过Filter向页面输出内容servletResponse.getWriter().write("<h1>hello MyFilter !</h1>");}@Overridepublic void destroy() {}}

创建名称为 FilterServlet 的 Servlet 类,代码如下。

package swadian.servlet.filter;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/FilterServlet")public class FilterServlet extends HttpServlet {private static final long serialVersionUID = 1L;public FilterServlet() {super();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {//设置向页面输出的格式与编码response.getWriter().write("<h3>FilterServlet 访问成功 !</h3>");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {doGet(request, response);}}

启动 Tomcat 服务器,在地址栏输入“http://localhost:8080/web/FilterServlet”,访问FilterServlet,结果如下图。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。