filter过滤器
filter
javaweb三大组件(servlet、filter、listener)之一。把对资源的请求拦截下来,从而实现一些特殊的功能。过滤器一般完成一些通用的操作,比如:权限控制、统一编码处理、敏感字符处理等。
快速入门
创建类实现filter,在类名上方写注解@WebFilter("拦截路径"):
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 放行前对request进行处理
System.out.println("filter...");
// 放行
chain.doFilter(request, response);
//放行后对response进行数据处理
}
}
filter访问对应资源,资源访问完成后,还会回到filter,再次回到filter是执行放行后的逻辑,流程如下:
graph TD
用户页面--请求-->filter放行前逻辑
filter放行前逻辑--filter放行-->资源servlet/jsp/html
资源servlet/jsp/html-->filter放行后逻辑
filter放行后逻辑--响应-->用户页面
过滤器链
一个web应用可以配置多个过滤器,这多个过滤器称为过滤器链。当过滤器的注解拦截路径相同时,会按照过滤器的类名自然排序来依次执行多个过滤器
小栗子,登录页面进行拦截:拦截登录以外的其他路径
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//强转,因为servlet的request里面没有getSession方法
HttpServletRequest req= (HttpServletRequest) request;
//获取session,判断用户是否登录,如果用户登陆了,session里面会有用户对象
HttpSession session = req.getSession();
Object user = session.getAttribute("user");
System.out.println(user);
if(user!=null){
//session里面有用户对象,说明用户已经登录,直接放行
chain.doFilter(request, response);
}else {
//表示用户没有登陆,拦截,并且跳转到登录页面
req.setAttribute("noThisUserMsg","用户还未登陆");
req.getRequestDispatcher("/loginPage.jsp").forward(req,response);
}
}
上面如果想拦截成功之后跳回到登陆页面,会发现页面的css、img、验证码、按钮、链接跳转的页面都被拦截了,因此需要加下面判断
String[] src={"register.html","login.jsp","/css/","/img/","checkCodeServlet","loginServlet"};
StringBuffer requestURL = req.getRequestURL();
for (String s : src) {
//如果包含上面的路径直接放行
if(requestURL.toString().contains(s)){
chain.doFilter(request,response);
return;
}
}