举个例子
假设在Web资源中,A资源要写5行代码,而B资源也要写一模一样的5行代码,这时就把这些代码都提取出来,
在过滤器里写这些代码,因为访问任何资源都要经过过滤器,在过滤器走一遍就可以,而不用访问资源一个接一个。
应用:权限控制,用户登录之后才能查看后台信息,而Web资源中都要判断一下是否登录,而这个操作就可以放在Filter中,通用操作。
1. Filter 快速入门
创建
FilterDemo
,配置@WebFilter("/*")
表示拦截所有,拦截记得要放行,要不然不能访问到对应的资源
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//1. 放行前,对 request数据进行处理
System.out.println("1.FilterDemo...");
//放行
chain.doFilter(request,response);
//2. 放行后,对Response 数据进行处理
System.out.println("5.FilterDemo...");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
2. Filter 执行流程
JSP的代码,验证执行的流程
<body>
<h1>hello JSP~</h1>
<%
System.out.println("2.hello jsp");
%>
</body>
过滤器代码
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//1. 放行前,对 request数据进行处理
System.out.println("1.FilterDemo...");
//放行
chain.doFilter(request,response);
//2. 放行后,对Response 数据进行处理
System.out.println("3.FilterDemo...");
}
控制台输出
3. Filter 使用细节
3.1 拦截路径配置
3.2 过滤器链
这里创建过滤器2
@WebFilter("/*")
public class FilterDemo2 implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//1. 放行前,对 request数据进行处理
System.out.println("2.FilterDemo...");
//放行
chain.doFilter(request,response);
//2. 放行后,对Response 数据进行处理
System.out.println("4.FilterDemo...");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
控制台打印顺序
当有很多过滤器时,确定执行顺序
4. 对登录案例进行改进
当没有进行登录时,还是通过改变URL路径来直接访问,这就存在不安全性;为了改进权限,设置过滤器,当用户已经登录过了,直接放行,未登录,返回登录页面显示未登录信息
创建LoginFilter
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)servletRequest;
// 判断访问资源路径是否和登录注册相关
String[] urls = {"/login.jsp", "/imgs/", "/css/", "/loginServlet", "/register.jsp", "/registerServlet", "/checkCodeServlet"};
// 获取当前访问资源的资源路径
String url = req.getRequestURL().toString();
// 循环判断
for (String u: urls
) {
if(url.contains(u)){
// 找到了
// 放行
filterChain.doFilter(req, servletResponse);
return;
}
}
//1. 如果访问的资源不是登录注册的,则判断session中是否有user
HttpSession session = req.getSession();
Object user = session.getAttribute("user");
//2. 判断user是否为null
if(user != null){
// 登陆过了
//放行
filterChain.doFilter(servletRequest, servletResponse);
}else {
// 跳转到登录页面,且提示信息
req.setAttribute("login_msg", "用户未登录");
req.getRequestDispatcher("/Login.jsp").forward(req, servletResponse);
}
}
@Override
public void destroy() {
}
}