javaweb之filter
过滤器
1、简单介绍
Filter:一个实现了特殊接口(Filter)的Java类. 实现对请求资源(jsp,servlet,html等)的过滤的功能.
过滤器是一个运行在服务器的程序, 优先于请求资源(Servlet或者jsp,html[动态资源和静态资源])之前执行. 过滤器是javaweb技术中最为实用的技术.
过滤器是在服务器上的一项技术,实现了特定的接口。作用是请求到达目标资源的时候,对发送过来的请求进行特殊处理。这里是一个条件判断,如果满足了我们设置的请求,那么需要将其放行;如果不满足,那么进行拦截。
首先对路径来进行拦截,如果说,执行了doFilter方法,那么就说明本次请求放行了;如果没有执行doFilter方法,那么本次请求执行没有执行成功
最常见的几种作用:
1、对于请求和响应乱码的情况;
2、对于权限管理。客户端发送请求,通过过滤器可以实现判断用户是什么角色,对应的界面显示该怎么去进行显示,拥有哪些功能。
3、黑名单过滤。不允许让黑名单中的用户来进行访问
2、Filter的生命周期
filter的生命周期和servlet的生命周期非常的类似
init(FilterConfig):初始化
doFilter(ServletReqeust req,ServletResponse resp,FilterChain chain):执行过滤的方法
destroy():销毁
对方法来进行描述:
- 服务器启动的时候, 会调用init()方法进行初始化【调用一次】
- 任何一次请求都会调用doFilter()方法进行过滤【路径相匹配】
- 服务器正常关闭或者项目从服务器移除, 调用destory()方法进行销毁【调用一次】
这里和servlet的init方法还是有区别的,servlet的init方法默认是在服务器启动之后,在第一次访问的时候执行初始化方法,但是servlet的init方法的执行之间是可以来进行设置的,可以设置在服务器启动的时候就执行init方法。
3、映射路径
filter的映射路径和servlet中的路径及其相似。
servlet的路径分为:完全路径匹配、目录匹配、扩展名匹配和缺省匹配
假设有一个管理员权限的过滤器,它应该对用户发出的管理员功能的请求进行条件的过滤。但是当用户发出登录、注册等请求的时候,不应该进行过滤。所以我们过滤器,应该有选择的过滤器请求。这就需要学习配置过滤器不同的映射路径,从而让过滤器过滤希望过滤器的请求。
3.1完全路径匹配
以"/"开始
/demo01 ---> 过滤器只能拦截路径/demo01;
3.2目录匹配
以"/"开始 以 *结束 .
/* --->当前项目下的所有的路径都可以拦截; /aa/* ---> 可以拦截 /aa/bb, /aa/bb/cc
3.3扩展名匹配
以"*"开始 例如: *.jsp *.do
*.do--->可以拦截路径的后缀是 do的 ; *.jsp--->拦截所有JSP
3.4缺省匹配
/ 除了jsp以外的资源都匹配
当前Filter里面不支持, Servlet里面可行的. 后面在Servlet里面遇到
4、拦截方式
有了上面学习的映射路径,我们可以控制过滤器过滤指定的内容,但是我们在访问资源的时候,并不是每次都是之间访问,有时是以转发的方式访问的,这就需要我们要让过滤器可以区分不同的访问资源的方式,有不同的拦截方式。 是通过 DispatcherType 来指定的.
- DispatcherType.REQUEST
默认值,过滤从浏览器发送过来的请求和重定向 不过滤转发
- DispatcherType.FORWARD
只过滤转发过来的请求
一般情况下, 转发我们不会过滤的. 转发属于服务器内部的行为. 直接使用默认值的情况偏多
案例:
/*只拦截转发*/
/*@WebFilter(urlPatterns = "/demo01",dispatcherTypes={DispatcherType.FORWARD})*/
/*转发,重定向,浏览器的直接请求都会拦截了*/
@WebFilter(urlPatterns = "/demo01",dispatcherTypes={DispatcherType.FORWARD,DispatcherType.REQUEST})
public class FilterDemo01 implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("FilterDemo01() 收到了请求...");
chain.doFilter(req, resp);
}
public void destroy() {
}
public void init(FilterConfig config) throws ServletException {
}
}
5、过滤器链
过滤器链作用:当一个filter收到请求的时候,调用chain.doFilter才可以访问下一个匹配的filter,若当前的filter是最后一个filter,调用chain.doFilter才能访问目标资源
用一个图来进行表示一下执行顺序
那么接下来举一个例子来演示一下:
AFilter:
@WebFilter(filterName = "AFilter",value = "/aa/*")
public class AFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
System.out.println("AFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤");
chain.doFilter(request, response);
}
}
BFilter
@WebFilter(filterName = "BFilter",value = "/aa/demo06")
public class BFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
System.out.println("BFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤");
chain.doFilter(request, response);
}
}
ServletDemo06:
@WebServlet(name = "ServletDemo06", value = "/aa/demo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("halo,浏览器端请求的资源被处理了");
}
}
浏览器端输入URL:http://localhost:8080/filter_war_exploded/aa/demo06
查看控制台:
AFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤
BFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤
halo,浏览器端请求的资源被处理了
6、字符编码过滤器
/**
* 为了让所有的请求中的字符编码都给设置好,所以将路径设置成所有的
*
* 需要注意的有三个点:
* 1、访问路径是:/*
* 2、需要将req和res进行强制类型转换;
* 3、将转换后的req和res来进行放行;
*/
@WebFilter(filterName = "EncodingFilter",value = "/*")
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 这里的这一步是可以将所有进行转换的req和res来进行转换,然后进行放行和过滤
chain.doFilter(req, res);
}
}