在SpringBoot中我們可以使用HandlerInterceptorAdapter這個適配器來實現自己的攔截器。這樣就可以攔截所有的請求並做相應的處理。
詳細可參考文章:https://www.cnblogs.com/weianlai/p/11358768.html
- 攔截器執行順序是按照Spring配置文件中定義的順序而定的。
- 會先按照順序執行所有攔截器的preHandle方法,一直遇到return false為止,比如第二個preHandle方法是return false,則第三個以及以后所有攔截器都不會執行。若都是return true,則按順序加載完preHandle方法。
- 然后執行主方法(自己的controller接口),若中間拋出異常,則跟return false效果一致,不會繼續執行postHandle,只會倒序執行afterCompletion方法。
- 在主方法執行完業務邏輯(頁面還未渲染數據)時,按倒序執行postHandle方法。若第三個攔截器的preHandle方法return false,則會執行第二個和第一個的postHandle方法和afterCompletion(postHandle都執行完才會執行這個,也就是頁面渲染完數據后,執行after進行清理工作)方法。(postHandle和afterCompletion都是倒序執行)
自定義一個攔截器需繼承HandlerInterceptorAdapter
package cn.jsfund.ngdp.support.config; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.alibaba.fastjson.JSONObject; import cn.jsfund.ngdp.support.exception.ServiceException; import cn.jsfund.ngdp.support.util.GetIpUtil; import cn.jsfund.ngdp.support.web.service.PermissionUserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import java.io.PrintWriter; @Configuration public class SecurityInterceptor extends HandlerInterceptorAdapter { private static Logger logger = LoggerFactory.getLogger(SecurityInterceptor.class); @Autowired private PermissionUserService permissionUserService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 請求地址 String requestUrl = request.getRequestURI().toString(); String userName = request.getRemoteUser(); // 無需攔截直接訪問的地址 String[] allowUrls = new String[] { "/api/Jurisdiction/getMenuList", "/logout", "/", "/api/user/getCurrentUser", "/swagger-resources/configuration/ui", "/swagger-resources" }; // 請求IP String ip = GetIpUtil.getIp(request); logger.info("request請求的用戶為:" + userName); logger.info("request請求的IP為:" + ip); logger.info("request請求的URL為:" + requestUrl); // 判斷請求地址是否無需攔擊 for (String url : allowUrls) { if (requestUrl.equals(url)) { return true; } } boolean checkFlag = false; if (permissionUserService.checkMenuJurisdiction(userName, requestUrl) > 0) { checkFlag = true; } if (!checkFlag) { JSONObject res = new JSONObject(); res.put("code", ServiceException.ERROR_VALIDATE); res.put("msg", "您沒有訪問權限"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); PrintWriter out = null; out = response.getWriter(); out.append(res.toString()); } return checkFlag; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle........."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion........."); } }
使攔截器生效需繼承WebMvcConfigurerAdapter(WebMvcConfigurer)類,可添加多個攔截器,按先后順序執行
package cn.jsfund.ngdp.support.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class InterceptorConf extends WebMvcConfigurerAdapter { @Autowired private SecurityInterceptor securityInterceptor; @Autowired private TestInterceptor testInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(securityInterceptor); registry.addInterceptor(testInterceptor); } }