Servlet之过滤器
过滤器Filter基本使用
注解方式:
创建一个Filter类实现Servlet的Filter接口,重写他的init()方法,doFilter()方法以及destroy()方法。
-
init() : 当Servlet容器启动时,初始化创建Filter,就会执行该方法,该方法只会执行一次。 -
doFilter(): 因为我配置的是/* 拦截,则每次Http请求都会执行一次doFilter方法。 -
destroy(): 当Servlet容器被销毁时,该过滤器也就被回收了,此时会调用destroy()方法,也只会执行一次。
注解方式执行多个过滤器时优先执行类名字典顺序在前的过滤器
@WebFilter("/*")
public class Demo1Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter init ...");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filter execute ...");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("filter destroy ...");
}
}
XML方式:
在web项目的WEB-INF下的web.xml配置文件中配置过滤器
如下配置,等同于上面的@WebFilter配置,当有多个过滤器时,则配置在前的优先执行。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<filter>
<filter-name>demoFilter</filter-name>
<filter-class>com.gitee.kenewstar.web.filter.Demo1Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>demoFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
注:当配置文件与注解方式混合使用时,配置文件的方式优先级更高,如果同一个Filter即使用了配置文件,又使用了注解方式,那么Servlet容器将会创建两个Filter对象,配置文件的优先级依然大于注解方式的Filter。
过滤器Filter的使用案例
案例一:限制静态资源访问
在doFilter()方法中,对请求URI路径做限制,判断是否属于静态资源请求,如果是静态资源请求,则转发到no_auth.html页面,表示无权访问
@WebFilter("/*")
public class StaticResourceFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("StaticResourceFilter init ...");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("StaticResourceFilter execute ...");
HttpServletRequest request = (HttpServletRequest) servletRequest;
if (request.getRequestURI().startsWith("/front")) {
request.getRequestDispatcher("no_auth.html").forward(servletRequest, servletResponse);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("StaticResourceFilter destroy ...");
}
}
访问结果如下:
案例二:基于过滤器实现登录验证
创建一个过滤器用于对登录做校验
首先判断请求是否/login路径,如果是则表示登录成功,并转发至test.html页面,如果不是/login 请求,则判断session中是否有user属性,如果没有,则跳转到no_auth.html页面,如果有,则继续往下执行。
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession();
if (Objects.equals(request.getRequestURI(), "/login")) {
session.setAttribute("user", "user");
request.getRequestDispatcher("/front/test.html").forward(request, response);
return;
}
if (session.getAttribute("user") == null) {
request.getRequestDispatcher("/front/no_auth.html").forward(request, response);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
no_auth.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>无权访问</title>
</head>
<body>
<h1>请登录后访问</h1>
<form action="/login" method="post">
<input type="submit" value="点击登录">
</form>
</body>
</html>
如下图所示,访问test.html。跳转至no_auth.html点击登录,则跳转到test.html页面
|