大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说Servlet过滤器(Filter)介绍和使用[亲测有效],希望您对编程的造诣更进一步.
使用Servlet的拦截器,我们需要使用到3个接口:Filter、FilterChain、FilterConfig
下面我们来介绍一下这几个接口
Filter接口
通过实现Filter接口,我们可以实现一个拦截器,从而实现对目标请求的拦截。Filter本质上也是一个Java程序,它和Servlet一样也是被Servlet容器调用和执行的。
我们在实现了拦截器之后,在web.xml中注册并指定需要拦截的请求。当Servlet容器调用某个Servlet程序的时候,如果发现已经注册了一个Filter程序对请求进行拦截,那么容器不会直接调用Servlet程序的 service 方法,而是调用Filter程序的 doFilter 方法,由doFilter方法来决定是否调用 service 方法。
Filter.doFilter 方法不能直接调用 Servlet的 service方法,而是通过调用 FilterChain.doFilter()来调用目标Servlet的 service方法。FilterChain对象是通过 doFilter 方法的参数传过来的。
** java.servlet.Filter接口 ** 定义了 三个方法:init、doFilter、destroy
- init方法
应用程序启动时,Web容器会根据web.xml配置信息来创建每个注册的Filter实例,并保存在内存中。
当容器创建Filter对象时,会调用init方法。init方法在整个生命周期中,只会被调用一次。Web容器在调用整个方法的时候,会传递一个包含了Filter配置信息和运行环境信息的 FilterConfig
对象。
public voic init(FilterConfig filterConfig) throws ServletException
-
doFilter方法
当目标Servlet被请求的时候,Servlet会先调用Filter的 doFilter 方法。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException.ServletException
其中,参数request和response是Web容器会上一个Filter传递过来的请求和响应对象。参数Chain代表当前Filter链对象。
-
destroy
该方法在Web容器卸载Filter对象之前被调用,在Filter的整个生命周期中仅会被调用一次。一般用来释放被该Filter对象占用的资源,例如:关闭数据库连接和IO流。
Filter链
可以存在有多个Filter对同一请求进行拦截,这样就形成了Filter链。Filter链中的各个Filter的拦截顺序是它们在web.xml文件中的配置顺序。
上一个 Filter.doFilter() 方法调用的 FilterChain.doFilter 方法调用的是下一个 Filter.doFilter方法。最后一个 Filter.doFilter 方法调用的 FilterChain.doFilter方法调用的是 目标Servlet的service方法。
FilterChain接口
该接口用于定义一个Filter链对象应该向外提供的方法,这个接口只定义了一个doFilter方法。
public void doFilter(ServletRequest request, ServletResponse response) throws java.io.IOException.ServletException
FilterChain接口的doFilter方法用于通知Web容器把请求交给Filter链中的下一个Filter去处理,如果当前调用此方法的Filter对象是Filter链中的最后一个Filter,那么将把请求交给目标Servlet程序去处理。
FilterConfig接口
与Servlet程序类似,Filter程序可能也要访问Servlet容器。Servlet规范将代表ServletContext对象和Filter配置的参数信息都封装到一个叫做FilterConfig的对象中。
FilterConfig接口定义FilterConfig对象应该向外提供的方法,以便在Filter程序中可以调用这些方法来获取ServletContext对象,以及获取在web.xml文件中为Filter配置的名称和初始化参数。
定义方法如下:
-
getFilterName方法,返回
<filter-name>
标签内的值 -
getServletContext方法,返回FilterConfig对象中所包装的对ServletContext对象的引用
-
getInitParameter方法,用于返回在web.xml文件中为Filter所设置的某个名称的初始化的参数值
-
getInitParameterNames方法,返回一个Enumeration集合对象
Filter的注册和映射
注册
<filter>
<filter-name>logFilter</filter-name>
<filter-class>com.xgc.filter.LogFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
映射
Filter的映射方式分为两种:资源访问请求路径、访问请求方式
指定资源访问请求路径
<filter-mapping>
<filter-name>logFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
拦截不同方式的请求路径
在web.xml文件中,每一个<filter-mapping>
元素都可以配置一个Filter所拦截的资源。在<filter-mapping>
元素中有一个特殊的子元素<dispatcher>
,该元素用于指定过滤器所拦截的资源被Servlet容器调用的方式。具体如下:
-
REQUEST(默认)
当用户直接访问Servlet,Web容器会调用过滤器。如果目标资源是通过
RequestDispatcher
的 include 或 forward 方法访问时,那么该过滤器将不会被调用。 -
INCLUDE
如果目标资源是通过
RequestDispatcher
的 include方法访问时,那么该过滤器将被调用 -
FORWARD
如果目标资源是通过
RequestDispatcher
的 forward方法访问时,那么该过滤器将被调用 -
ERROR
如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。
使用例子
查看项目目录
LogFilter:
package com.xgc.filter;
import javax.servlet.*;
import java.io.IOException;
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("目标Servlet的service方法执行前");
chain.doFilter(request, response);
System.out.println("目标Servlet的service方法执行后");
}
}
TestServlet:
package com.xgc.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
public class TestServlet extends HttpServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("处理请求");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>com.xgc.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
<filter>
<filter-name>logFilter</filter-name>
<filter-class>com.xgc.filter.LogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>logFilter</filter-name>
<url-pattern>/test</url-pattern>
</filter-mapping>
</web-app>
将项目运行起来,访问路径 http://localhost:8080/javaweb/test
在IDE控制台会发现下面输出:
我们可以发现,通过拦截器,我们可以在目标Servlet的service方法执行前后进行其他处理。
参考文章
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13542.html