Servlet过滤器
过滤器概念
Servlet过滤器是一种可插拔式的组件规范,可以动态的拦截请求与响应对象,针对客户端需要访问的数据或者资源做一些预处理的干预过程,我们称为过滤器。
我们可以将一个或者多个过滤器添加到一个或一组Servlet上,也可以附加到JSP(JavaServer Pages)文件和HTML(HyperText Markup Language)页面,在调用对应的Servlet时会首先调用Servlet过滤器进行相关的预处理
过滤器作用
- 客户端发送请求访问服务端的相关资源时,Servlet过滤器会对请求对象进行拦截,动态的处理请求对象中的数据信息,及拦截请求对象进行预处理
- 服务器处理完成相关业务后会通过响应对象返回给客户端,而此时会先通过Servlet过滤器,得到响应对象的数据信息,从而返回给客户端,及拦截响应对象金进行预处理
过滤器的配置方式
web.xml配置及各节点说明
<!--配置登录的过滤器-->
<!--指定一个过滤器-->
<filter>
<!--指定过滤器的名称,且不能为空-->
<filter-name>LoginFilter</filter-name>
<!--指定当前过滤器的完整限定类名-->
<filter-class>org.soffteem.filter.LoginFilter</filter-class>
<!--指定过滤器的初始化参数-->
<init-param>
<!--指定初始化参数名称-->
<param-name>encoding</param-name>
<!--指定初始化参数值-->
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--配置一个过滤器Filter拦截的请求资源,资源的两种方式:1、Servlet名称 2、资源访问路径-->
<filter-mapping>
<!--filter子元素声明的名称,必须与<filter-name>节点的名称保持一致-->
<filter-name>LoginFilter</filter-name>
<!--设置过滤器拦截的资源请求-->
<url-pattern>/friend_demo/login</url-pattern>
</filter-mapping>
注解配置
@WebFilter(filterName = "LoginFilter",urlPatterns = {"/friend_demo/login"},initParams = {
@WebInitParam(name="encoding",value = "utf-8")
})
注解名称与参数 | 含义 |
---|---|
@WebFilter() | 等价于web.xml配置中filter节点(声明一个过滤器) |
@WebInitParam() | 等价于web.xml配置中init-param节点(配置过滤器初始化的参数) |
filterName 属姓名 | 等价于web.xml配置中filter-name节点(配置过滤器名称) |
urlPatterns 属姓名 | 等价于web.xml配置中url-pattern节点(过滤器拦截的资源请求) |
initParams属性名 | 声明初始化的参数,由@WebInitParam()注解组成 |
name属性名 | 等价于web.xml配置中param-name节点(设置初始化参数名称) |
value 属性名 | 等价于web.xml配置中param-value节点(设置初始化参数值) |
多个过滤器的执行顺序与原理图
我们的应用程序中可以根据不同的业务配置多个Servlet过滤器,假设我们当前配置了MyFilter与LoginFilter两个过滤器就需要配置两个过滤器,配置方法通过我上面所述的两种基本一致
我们需要将过滤器的配置尽量配置到Servlet的上面,原因是我们在调用对应的Servlet执行业务时会先调用当前Servlet添加的Servlet过滤器。过滤器的执行顺序由filter-mapping决定若要更换过滤器执行的顺序,只需要将filter-mapping配置顺序执进行颠倒即可
过滤器执行的原理图如下
过滤器方法
1、public void init(FilterConfig filterConfig)
我们的应用程序启动时,容器就会通过该init初始化方法进行Filter对象的构建,完成对象的初始化操作,为后面的拦截请求资源准备,该方法只会调用一次且Filter对象也只会创建一次,我们可以通过FilterConfig对象获取请求中存储的数据信息
2、public void doFilter (ServletRequest, ServletResponse, FilterChain)
doFilter ()方法会完成我们对应的过滤业务操作,只有当客户端发送资源请求后被过滤器匹配到就会调用。我们可以通过过滤器链filterChain调用doFilter方法携带请求与响应对象执行下一个过滤器。若存在下一个过滤器就执行下一个,否则执行对应的操作业务
3、public void destroy()
destroy()方法是检测Servlet过滤器实例销毁时进行调用,并且会释放当前Servlet过滤器占用的资源
过滤器案例
@WebFilter(filterName = "LoginFilter",urlPatterns = {"/friend_demo/login"},initParams = {
@WebInitParam(name="encoding",value = "utf-8")
})
public class LoginFilter implements Filter {
//String encode;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//获取初始化参数
//this.encode = filterConfig.getInitParameter("encoding");
System.out.println("初始化Servlet过滤器Filter对象.......");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("调用doFilter()方法执行相关业务.....");
//System.out.println("获取初始化的参数:" + this.encode);
//通过过滤器链,若存在下一个过滤器则继续执行,否则执行相关业务
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("调用销毁destroy()方法.......");
}
}
感谢大家的阅读,热爱分享的仓鼠,请大家多多指教,么么哒~~~~~