一.新建過濾器
這里我以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; }