1. 程式人生 > >springboot的兩種實現攔截器的方法

springboot的兩種實現攔截器的方法

一、使用Interceptor攔截器

1.首先新建一個攔截器實現HandlerInterceptor介面

以一個簡單的token驗證為例,驗證通過,將使用者資訊放入作用域,返回true

不通過返回false

  1. @Service
  2. public class UserTokenInterceptor implements HandlerInterceptor {
  3. @Autowired
  4. private SysusertokenMapper sysusertokenMapper;
  5. @Autowired
  6. private SysloginuserMapper sysloginuserMapper;
  7. @Autowired
  8. private SysuserMapper sysuserMapper;
  9. @Override
  10. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
  11. throws Exception {
  12. // 在請求處理之前進行呼叫(Controller方法呼叫之前),返回true才會繼續往下執行,返回false取消當前請求
  13. boolean isAccess = false;
  14. String tokenCode = request.getHeader("Token"
    );
  15. if (tokenCode != null && !"".equals(tokenCode)) {
  16. //查詢未過期的
  17. Sysusertoken sysusertoken = sysusertokenMapper.selectByTokenCode(tokenCode);
  18. if (sysusertoken != null) {
  19. Sysloginuser sysloginuser = sysloginuserMapper.selectByPrimaryKey(sysusertoken.getLoginid());
  20. Sysuser sysuser = sysuserMapper.selectByPrimaryKey(sysloginuser.getUserid());
  21. request.getSession().setAttribute("user",sysuser);
  22. request.getSession().setAttribute("token",tokenCode);
  23. isAccess = true;
  24. }
  25. }
  26. return isAccess;
  27. }
  28. @Override
  29. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
  30. ModelAndView modelAndView) throws Exception {
  31. }
  32. @Override
  33. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
  34. throws Exception {
  35. }
  36. }

2.新建一個配置類來管理攔截器,將你之前新建的攔截器注入進來

addPathPatterns("/**")是攔截所有請求

excludePathPatterns("","",...)配置無需攔截的請求

  1. package com.gcexe.monitor.filter;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Component;
  4. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
  6. @Component
  7. public class UserTokenAppConfigurer extends WebMvcConfigurationSupport{
  8. @Autowired
  9. private UserTokenInterceptor userTokenInterceptor;
  10. @Override
  11. public void addInterceptors(InterceptorRegistry registry) {
  12. // 多個攔截器組成一個攔截器鏈
  13. // addPathPatterns 用於新增攔截規則
  14. // excludePathPatterns 使用者排除攔截
  15. registry.addInterceptor(userTokenInterceptor).addPathPatterns("/**")
  16. .excludePathPatterns("/account/login","/account/register");
  17. super.addInterceptors(registry);
  18. }
  19. }

注意加上@Component註解,使其可以被掃描到

二、使用servlet的filter攔截器

新建一個類實現javax.servlet.Filter介面,通過@WebFilter註解來配置要攔截的請求,doFilter方法是要進行的操作。

  1. package com.gcexe.monitor.filter;
  2. import java.io.IOException;
  3. import java.util.Arrays;
  4. import javax.servlet.Filter;
  5. import javax.servlet.FilterChain;
  6. import javax.servlet.FilterConfig;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.ServletRequest;
  9. import javax.servlet.ServletResponse;
  10. import javax.servlet.annotation.WebFilter;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Component;
  15. import com.gcexe.monitor.persistence.dao.SysloginuserMapper;
  16. import com.gcexe.monitor.persistence.dao.SysuserMapper;
  17. import com.gcexe.monitor.persistence.dao.SysusertokenMapper;
  18. import com.gcexe.monitor.persistence.entity.Sysloginuser;
  19. import com.gcexe.monitor.persistence.entity.Sysuser;
  20. import com.gcexe.monitor.persistence.entity.Sysusertoken;
  21. @Component
  22. @WebFilter(urlPatterns = "/**", filterName = "monitorFilter")
  23. public class TokenAuthorFilter implements Filter {
  24. @Autowired
  25. private SysusertokenMapper sysusertokenMapper;
  26. @Autowired
  27. private SysloginuserMapper sysloginuserMapper;
  28. @Autowired
  29. private SysuserMapper sysuserMapper;
  30. private static final String[] excludePathPatterns = { "/monitor/account/login", "/monitor/account/register" };
  31. @Override
  32. public void init(FilterConfig filterConfig) throws ServletException {
  33. // TODO Auto-generated method stub
  34. }
  35. @Override
  36. public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
  37. throws IOException, ServletException {
  38. // 在請求處理之前進行呼叫(Controller方法呼叫之前),返回true才會繼續往下執行,返回false取消當前請求
  39. boolean isFilter = false;
  40. HttpServletRequest request = (HttpServletRequest) req;
  41. HttpServletResponse response = (HttpServletResponse) resp;
  42. // 不攔截登陸和註冊
  43. String url = request.getRequestURI();
  44. if (Arrays.asList(excludePathPatterns).contains(url)) {
  45. chain.doFilter(request, response);
  46. return;
  47. }
  48. String tokenCode = request.getHeader("Token");
  49. if (tokenCode != null && !"".equals(tokenCode)) {
  50. // 查詢未過期的
  51. Sysusertoken sysusertoken = sysusertokenMapper.selectByTokenCode(tokenCode);
  52. if (sysusertoken != null) {
  53. Sysloginuser sysloginuser = sysloginuserMapper.selectByPrimaryKey(sysusertoken.getLoginid());
  54. Sysuser sysuser = sysuserMapper.selectByPrimaryKey(sysloginuser.getUserid());
  55. request.getSession().setAttribute("user", sysuser);
  56. request.getSession().setAttribute("token", tokenCode);
  57. isFilter = true;
  58. }
  59. }
  60. if (isFilter) {
  61. chain.doFilter(request, response);
  62. }
  63. }
  64. @Override
  65. public void destroy() {
  66. // TODO Auto-generated method stub
  67. }
  68. }

執行chain.doFilter(request,response)方法類似於上面的返回true,讓程式繼續往下執行

可以自己配置返回內容,無需攔截的請求,我這裡是定義了一個數組,自行判斷,對應地址直接執行chain.doFilter(reuqest.response),同樣注意加上@Component註解

兩種方式均可以使用,相比較而言,第一種方式較為方便,我一開始也是使用的這種,但是後來需要整合Spring Boot Validator框架時,發現驗證資料一直不生效,後來發現是和Inteceptor有衝突,去掉攔截就可以驗證了,暫時還沒找到解決的辦法,所以改為使用第二種方法。