过滤器
过滤器是客户端和服务端之间的一个过滤网,它主要作用就是客户端在访问目标资源之前对请求和响应进行一系列的规则条件设置,符合条件放行,不符合就不放行。也可以进行一些逻辑设置。如果有多个资源共用一段代码,此时可以考虑使用过滤器进行提取。还有就是对request和response进行增强
即有以下三个主要作用:
1,设置权限,符合放行不符合不放行
2,增强request和response,通过ServletRequestWrapper和ServletResponseWrapper两个类来进行增强
3,提取公共代码,比如解决中文乱码的相关设置,在访问目标资源前进行一些逻辑设置
一,filter如何使用?
filter访问过程大概如下
客户端发起一个请求,服务器让这个请求先经过过滤器代码,过滤器执行dofilter()后在继续执行后续过滤器的代码直到最后访问到目标资源。比如你要访问目标资源前要先设置好中文乱码的配置以及判断用户是否登入就可以分别用两个过滤器.第一个用来设置中文乱码,第二个用来判断是否登入,如果没有登入就让它跳转登入页面。如果登入就让它继续访问目标资源。
1,filter代码基本实现
(1)创建一个类实现Filter对象并实现init,doFilter,destory三个方法。当然在IDE中可以直接在新建文件的时候选择filter,代码如下:
public class FilterDemo implements Filter {
@Override
public void destroy() { }
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//执行一句输出
System.out.println("filter running");
chain.doFilter(req, resp);
}
@Override
public void init(FilterConfig config) throws ServletException {}
}
//创建一个servlet目标资源
public class ServletDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("servlet");
}
}
接着在web.xml进行过滤器配置
<filter>
<!--过滤器名称-->
<filter-name>FilterDemo</filter-name>
<!--全包名-->
<filter-class>filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<!--过滤器名称,和上面的filter-name对应-->
<filter-name>FilterDemo</filter-name>
<!--需要进行过滤的资源配置,/*表示所有资源都要进行该过滤器过滤-->
<url-pattern>/*</url-pattern>
</filter-mapping>
配置和servlet的有点类似
其中 url-pattern表示需要进行该过滤器过滤的资源路径配置,有三种配置方式
1,/* 表示所有资源都要经过该过滤器过滤
2,* .java 表示所有以java为扩展名的资源都要经过该过滤器过滤
2,/abc/ * 表示abc文件夹下的资源需要经过该过滤器过滤
启动项目并执行该目标资源ServletDemo
结果如下所示:
说明了在执行目标servlet之前它先经过了过滤器。
2,有多个过滤器时,过滤器会按web配置的顺序来执行
//在创建一个filter2代码如下
public class FilterDemo2 implements Filter {
@Override
public void destroy() {}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("filter2");
chain.doFilter(req, resp);
}
@Override
public void init(FilterConfig config) throws ServletException {}
}
//同时这样进行配置
<!--多个过滤器存在时按照配置的顺序来执行.这里先执行FilterDemo,然后在执行FilterDemo2-->
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>FilterDemo2</filter-name>
<filter-class>filter.FilterDemo2</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
上述情况,在访问目标资源的时候就会先进行FilterDemo的过滤然后在执行FilterDemo2
启动项目,访问servlet效果如下:
3,filter的生命周期
(1)filter的创建
filter在服务器启动的时候就会创建并执行init()方法
//在init()方法中输出一句话
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("init");
}
然后启动项目观察控制台日志
可以发现filter已经创建
(2)filter的销毁
在服务器关闭的时候filter会销毁并执行destory方法
//在destory方法中输出一句话
@Override
public void destroy() {
System.out.println("destory");
}
此时关闭服务器
此时filter已经被销毁
4,filter在web.xml的一些其他配置
在web.xml中除了基本的配置外还可以配置初始化参数以及filter的执行条件
(1)配置初始化参数
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>filter.FilterDemo</filter-class>
<!--配置初始化参数-->
<init-param>
<param-name>name</param-name>
<param-value>zhangsan</param-value>
</init-param>
</filter>
这样就可以在init方法中使用参数的FilterConfig的getInitParameter来获取参数
//获取初始化参数
public void init(FilterConfig config) throws ServletException {
String name = config.getInitParameter("name");
System.out.println(name);
}
(2)配置filter执行条件
filter默认在直接访问目标资源的时候会执行,在filter-mappering中配置dispatcher就可以配置filter的执行条件
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
<!--配置访问条件-->
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
dispatcher值:
1,REQUEST 直接访问目标资源时执行,即输入网址然后回车那样直接发起请求。或者重定向
2,FORWARD:转发时才执行filter,执行 request.getRequestDispatcher().forward();来访问目标资源时执行
3,INCLUDE: 包含资源时执行filter,执行 request.getRequestDispatcher().include();时执行
4,ERROR:发生错误,进行跳转时执行filter,即系统出错报500时
系统默认的是REQUEST.–>实际开发中也很少用到其他三种方式