Filter 是浏览器访问Servlet前要执行的部分。
添加 Filter
实现Filter接口,并添加@WebFilter
注解即可:
@WebFilter("/*") //路径的匹配规则和Servlet一致,这里表示匹配所有请求
public class TestFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
System.out.println(request.getRequestURL());
filterChain.doFilter(servletRequest, servletResponse);
}
}
现在我们发起的所有请求,一律需要经过此过滤器。
filterChain.doFilter(servletRequest, servletResponse);
通过在最后添加该语句,将请求继续传输给下一个过滤器,只有当执行该代码后没有过滤器可以传输时,才会传输给Servlet。
实际上,当
doFilter
方法调用时,就会一直向下直到Servlet,在Servlet处理完成之后,又依次返回到最前面的Filter,类似于递归的结构。
HttpFilter 实现类
同Servlet一样,Filter也有对应的HttpFilter专用类,它针对HTTP请求进行了专门处理,因此我们可以直接使用HttpFilter来编写:
public abstract class HttpFilter extends GenericFilter {
private static final long serialVersionUID = 7478463438252262094L;
public HttpFilter() {
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
this.doFilter((HttpServletRequest)req, (HttpServletResponse)res, chain);
} else {
throw new ServletException("non-HTTP request or response");
}
}
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
chain.doFilter(req, res);
}
}
实现未登录禁止访问
用户在未登录情况下,只允许静态资源和登陆页面请求通过,登陆之后畅行无阻:
@WebFilter("/*")
public class MainFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String url = req.getRequestURL().toString();
//判断是否为静态资源
if(!url.endsWith(".js") && !url.endsWith(".css") && !url.endsWith(".png")){
HttpSession session = req.getSession();
User user = (User) session.getAttribute("user");
//判断是否未登陆
if(user == null && !url.endsWith("login")){
res.sendRedirect("login");
return;
}
}
//交给过滤链处理
chain.doFilter(req, res);
}
}