一.新建过滤器
这里我以session登录校验为例写了一个过滤器的例子
1.先写一个通过用户名密码登录的小栗子(用户名、密码都是root)
@Controller @RestController public class LoginController { @RequestMapping("login") public String login(String name,String pwd,HttpServletRequest request) { HttpSession session = request.getSession(); if(name.equals("root")&&pwd.equals("root")) { User user = new User(); user.setName(name); session.setAttribute("user",user); return "登录成功"; } else { return "用户名或密码错误!"; } } }
2.写登录校验的过滤器
1.新建一个SessionFilter 实现(implements)javax.servlet.Filter接口,并重写其中的方法
public class SessionFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { } @Override public void destroy() { } }
2.详细代码
public class SessionFilter implements Filter { //标示符:表示当前用户未登录(可根据自己项目需要改为json样式) String NO_LOGIN = "您还未登录"; //不需要登录就可以访问的路径(比如:注册登录等) String[] includeUrls = new String[]{"/login","register"}; @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(false); String uri = request.getRequestURI(); System.out.println("filter url:"+uri); //是否需要过滤 boolean needFilter = isNeedFilter(uri); if (!needFilter) { //不需要过滤直接传给下一个过滤器 filterChain.doFilter(servletRequest, servletResponse); } else { //需要过滤器 // session中包含user对象,则是登录状态 if(session!=null&&session.getAttribute("user") != null){ // System.out.println("user:"+session.getAttribute("user")); filterChain.doFilter(request, response); }else{ String requestType = request.getHeader("X-Requested-With"); //判断是否是ajax请求 if(requestType!=null && "XMLHttpRequest".equals(requestType)){ response.getWriter().write(this.NO_LOGIN); }else{ //重定向到登录页(需要在static文件夹下建立此html文件) response.sendRedirect(request.getContextPath()+"/user/login.html"); } return; } } } /** * @Author: xxxxx * @Description: 是否需要过滤 * @Date: 2018-03-12 13:20:54 * @param uri */ public boolean isNeedFilter(String uri) { for (String includeUrl : includeUrls) { if(includeUrl.equals(uri)) { return false; } } return true; } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
3.过滤器的配置
过滤器的配置有2种方式,第一种是纯注解的方式,第二种是写过滤器注册配置类
1.通过注解方式配置过滤器
- 在过滤器上添加WebFilter注解
- 在启动类添加ServletComponentScan注解
@WebFilter(filterName = "sessionFilter",urlPatterns = {"/*"}) public class SessionFilter implements Filter { }
@SpringBootApplication @ServletComponentScan public class FileUploadApplication { public static void main(String[] args) { SpringApplication.run(FileUploadApplication.class, args); } }
2.通过过滤器注册配置类使用过滤器
@Configuration public class WebComponent2Config { @Bean public FilterRegistrationBean someFilterRegistration1() { //新建过滤器注册类 FilterRegistrationBean registration = new FilterRegistrationBean(); // 添加我们写好的过滤器 registration.setFilter( new SessionFilter()); // 设置过滤器的URL模式 registration.addUrlPatterns("/*"); return registration; } }
4.测试一下
1.不登录,访问other(localhost/user/other.html)
回车
因为没有登录所以重定向到了登录页
2.登录
http://localhost/login?name=root&pwd=root
3.再访问other(localhost/user/other.html)
这次是登录状态,所以过滤器放行,能成功进入other
5.拓展
当有多个过滤器需要按顺序执行时怎么办?
使用注解的配置方法不能配置顺序,但是可以通过过滤器名字的字典顺序实现顺序过滤(比如AFilter就会在BFilter前执行),显然这种方法看起来不怎么正经。
但是我们可以使用第二种配置方法.
通过给注册类设置order,order越小,执行优先级越高
@Bean public FilterRegistrationBean someFilterRegistration1() { //新建过滤器注册类 FilterRegistrationBean registration = new FilterRegistrationBean(); // 添加我们写好的过滤器 registration.setFilter( new SessionFilter()); // 设置过滤器的URL模式 registration.addUrlPatterns("/*"); //设置过滤器顺序 registration.setOrder(1); return registration; }