浅谈filter中的chain.doFilter(request, response)的作用
filter在web开发中可谓是神通广大,想必大家都有所了解,在这里不作赘述。
下面主要谈一谈chain.doFilter(request, response);这条语句是怎么回事,过滤器的作用就是之一就是在用户的请求到达servlet之前,拦截下来做预处理,处理之后便执行chain.doFilter(request, response)这个方法,如果还有别的过滤器,那么将处理好的请求传给下个过滤器,依此类推,当所有的过滤器都把这个请求处理好了之后,再将处理完的请求发给servlet;如果就这一个过滤器,那么就将处理好的请求直接发给servlet。
import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 检查用户是否已经完成登录
*/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*") //filterName(拦截器的名字),urlPatterns(拦截路径)
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符(比较两个路径是否相同)
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1。获取本次请求的URI
String requestURI = request.getRequestURI(); // /backend/index.html
log.info("拦截到请求:{}", requestURI);
//定义不需要处理的请求路径
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**",
"/user/sendMsg", //移动端发送短信
"/user/login", //移动端登录
};
//2.判断本次请求是否需要处理
boolean check = check(urls,requestURI);
//3.如果不需要处理,则直接放行
if(check){
log.info("本次请求{}不需要处理", requestURI);
filterChain.doFilter(request,response); // 传递到下一个Filter,如果没有下一个过滤器,则返回当前请求的资源(也就是你在地址栏输入的地址)
return;
}
//4-1.判断登录状态,如果已登录,则直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
/**
* 将id存入BaseContext中
*/
Long empId = (Long) request.getSession().getAttribute("employee");
BaseContext.setCurrentId(empId);
filterChain.doFilter(request,response);
return;
}
//4-2.判断登录状态,如果已登录,则直接放行(移动端)
if(request.getSession().getAttribute("user") != null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("user"));
/**
* 将id存入BaseContext中
*/
Long userId = (Long) request.getSession().getAttribute("user");
BaseContext.setCurrentId(userId);
filterChain.doFilter(request,response);
return;
}
log.info("用户未登录");
//5.如果未登录,则返回未登录结果,通过输出流方式向客户端页面相应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls, String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match){
return true;
}
}
return false;
}
}