1、过滤器概述
- 定义:动态拦截或响应请求
- 拦截:在客户端的请求访问后端资源之前,拦截这些请求;
- 响应:在服务器的相应发送给客户端之前,处理这些响应。
2、Filter生命周期
Ⅰ、init(FilterConfig filterConfig) :只容器初始化的时候调⽤⼀次,即应⽤启动的时候加载⼀次 ;
Ⅱ、doFilter(ServletRequest request, ServletResponse response, FilterChain chain) :只要命中 过滤规则就触发,可以在filter中根据条件决定是否调用;
Ⅲ、chain.doFilter(request, response):即是否让⽬标资源执⾏ destroy() ,只容器销毁的时候调⽤⼀次,即应⽤停⽌的时候调⽤⼀次。
- 范例:生命周期demo
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(filterName = "cookieServlet",urlPatterns = {"/get_cookie_test"})
public class CustomFilter implements Filter {
// 1、初始化过滤器
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CustomFilter init ");
}
// 2、设置过滤器规则
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("CustomFilter doFilter ");
//让请求继续往下走
chain.doFilter(request,response);
}
// 3、销毁过滤器
@Override
public void destroy() {
System.out.println("CustomFilter destroy ");
}
}
- 运行结果
- 查看页面
3、WebFilter元注解
- 元注解参数如下
//该Filter是否⽀持异步操作模式
asyncSupported
//指定Filter对那种dispatcher模式进⾏过滤 该属性⽀持 Async,Error
Forward,include,request
dispatcherType
//Filter 显示的名称
displayName
//Filter的名称
filterName
//Filter的配置参数
initParams
//过滤的Servlet可以指定多个,表示对这⼏个特定的的servlet 进⾏过滤
servletNames
//指定 Filter拦截的 URL,和上⾯的servletNames配置⼀样,⽤*可以表示通配符,但是不⽤字⺟后
加*,应该按照模块划分,⽐如/user/*
urlPatterns/value
- 范例:拦截器demo
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//@WebFilter(filterName = "xxx",servletNames = {"cookieServlet"},urlPatterns = {"/user/*","/order/*"})
// 业务要求:拦截全部请求 /*
@WebFilter(filterName = "AAA",urlPatterns = {"/*"})
public class CustomFilter implements Filter {
// 1、过滤器初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CustomFilter init ");
}
// 2、定义过滤器规则
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("CustomFilter doFilter ");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
//让请求继续往下走
chain.doFilter(request,response);
}
// 3、销毁过滤器
@Override
public void destroy() {
System.out.println("CustomFilter destroy ");
}
}
- 访问页面
http://localhost:8080/
http://localhost:8080/get_cookie_test
- 运行结果:
4、ServletFilte参数详解
-
指定Filter对那种dispatcher模式进⾏过滤,不符合的则不进⾏过滤
- REQUEST:默认值,浏览器直接请求的资源会被过滤器拦截
- FORWARD:转发访问资源会被过滤器拦截
- INCLUDE:包含访问资源
- ERROR:错误跳转资源
- ASYNC:异步访问资源
-
范例
// 拦截全部请求 /*
@WebFilter(filterName = "AAA",urlPatterns = {"/*"},initParams = {
@WebInitParam(name = "encoding",value = "UTF-8"),
@WebInitParam(name = "loginPage",value = "/login.jsp"),
},dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})
public class CustomFilter implements Filter {
private FilterConfig filterConfig;
// 1、过滤器初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CustomFilter init ");
this.filterConfig = filterConfig;
// 获取过滤器名称
String filterName = filterConfig.getFilterName();
System.out.println(filterName);
}
// 2、设置过滤规则
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("CustomFilter doFilter ");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
//让请求继续往下走
chain.doFilter(request,response);
}
// 3、销毁过滤器
@Override
public void destroy() {
System.out.println("CustomFilter destroy ");
}
}
- 运行结果
5、项目实战
- 业务场景:用户登录访问个人页面拦截
(1)配置文件
- 新建user/user.jsp
<html>
<head>
<title>Title</title>
</head>
<body>
id:${loginUser.id}
<br>
name:${loginUser.name}
<a href="/logout_servlet">退出</a>
</body>
</html>
- 新建配置文件web/login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="<%=request.getContextPath()%>/loginServlet" method="post">
名称:<input type="text" name="name"/>
<br/>
密码:<input type="password" name="pwd"/>
<input type="submit" value="登录">
消息提示 ${msg}
</form>
</body>
</html>
(2)代码实战
@WebFilter(filterName = "loginFilter",urlPatterns = {"/user/*","/order/*"},initParams = {
@WebInitParam(name = "encoding",value = "UTF-8"),
@WebInitParam(name = "loginPage",value = "/login.jsp"),
})
public class LoginFilter implements Filter {
private FilterConfig filterConfig;
private String encoding;
private String loginPage;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CustomFilter init ");
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
this.loginPage = filterConfig.getInitParameter("loginPage");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("CustomFilter doFilter ");
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
response.setContentType("text/html;charset=utf-8");
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
//session里面有用户信息
if(httpServletRequest.getSession().getAttribute("loginUser") !=null){
chain.doFilter(request,response);
}else {
httpServletRequest.setAttribute("msg","非法访问,请登录");
httpServletRequest.getRequestDispatcher(loginPage).forward(httpServletRequest,httpServletResponse);
}
}
@Override
public void destroy() {
System.out.println("CustomFilter destroy ");
}
}
(3)运行结果
Ⅰ、浏览器访问结果:访问http://localhost:8080/user/user.jsp
Ⅱ、IDEA运行结果
Ⅲ、浏览器访问结果:访问http://localhost:8080/user/user.jsp,输入