Java專案微服務中新增攔截器實現
阿新 • • 發佈:2018-11-08
目的:專案中需要攔截器的實現,讓沒有登陸的使用者無法通過url來實現頁面的渲染。
實現:
一、繼承HandlerInterceptorAdapter
public class LoginInterceptor extends HandlerInterceptorAdapter
二、重寫preHandler和afterCompletion
preHandler:前置方法,可以攔截在controller之前,return false被攔截,return true被放行
afterCompletion:完成方法,當檢視渲染完成之後執行
/** * 前置方法:在handler方法執行之前執行 * false-被攔截 * true-放行 * @param request * @param response * @param handler * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 獲取token資訊 String token = CookieUtils.getCookieValue(request, this.jwtProperties.getCookieName()); // 判斷token是否為空 if (StringUtils.isBlank(token)) { // 沒有登入,跳轉到登入頁 response.sendRedirect("登陸頁面的url(從上個頁面進入登陸頁面的url)"); return false; } // 解析jwt UserInfo userInfo = JwtUtils.getInfoFromToken(token, this.jwtProperties.getPublicKey()); if (userInfo == null) { response.sendRedirect("登陸頁面的url(從上個頁面進入登陸頁面的url)"); return false; } THREAD_LOCAL.set(userInfo); return true; } /** * 完成方法:在檢視渲染完成之後執行 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 必須要釋放資源,使用的是tomcat執行緒池,業務邏輯處理完成之後,執行緒並沒有結束,還回到執行緒池中了 THREAD_LOCAL.remove(); }
三、使用ThreadLocal共享使用者資訊資料UserInfo
設定到ThreadLocal中在後續的業務邏輯中就可以使用UserInfo資料
private static final ThreadLocal<UserInfo> THREAD_LOCAL = new ThreadLocal<>();
THREAD_LOCAL.set(userInfo);
完整的攔截器程式碼:
@EnableConfigurationProperties(JwtProperties.class) @Component public class LoginInterceptor extends HandlerInterceptorAdapter { private static final ThreadLocal<UserInfo> THREAD_LOCAL = new ThreadLocal<>(); public LoginInterceptor(JwtProperties jwtProperties) { this.jwtProperties = jwtProperties; } @Autowired private JwtProperties jwtProperties; /** * 前置方法:在handler方法執行之前執行 * false-被攔截 * true-放行 * @param request * @param response * @param handler * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 獲取token資訊 String token = CookieUtils.getCookieValue(request, this.jwtProperties.getCookieName()); // 判斷token是否為空 if (StringUtils.isBlank(token)) { // 沒有登入,跳轉到登入頁 response.sendRedirect("登陸頁面的url(從上個頁面進入登陸頁面的url)"); return false; } // 解析jwt UserInfo userInfo = JwtUtils.getInfoFromToken(token, this.jwtProperties.getPublicKey()); if (userInfo == null) { response.sendRedirect("登陸頁面的url(從上個頁面進入登陸頁面的url)"); return false; } THREAD_LOCAL.set(userInfo); return true; } /** * 完成方法:在檢視渲染完成之後執行 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 必須要釋放資源,使用的是tomcat執行緒池,業務邏輯處理完成之後,執行緒並沒有結束,還回到執行緒池中了 THREAD_LOCAL.remove(); } /** * 獲取執行緒變數中的引數 * @return */ public static UserInfo get() { return THREAD_LOCAL.get(); } }
四、啟動攔截器
兩個條件:1、實現WebMvcConfigurer介面 2、新增@Configuration註解
重寫addInterceptors方法:
@Override
public void addInterceptors(InterceptorRegistry registry)
五、新增攔截器和攔截路徑
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor()).addPathPatterns("/**"); }
其中的addPathPatterns("/**")是指攔截所有的路徑
完整啟動攔截器程式碼:
@Configuration
@EnableConfigurationProperties(JwtProperties.class)
public class ProjectConfig implements WebMvcConfigurer {
@Autowired
private JwtProperties jwtProperties;
@Bean
public LoginInterceptor loginInterceptor() {
return new LoginInterceptor(jwtProperties);
}
/**
* 註冊攔截器到攔截器註冊器中,使攔截器生效
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor()).addPathPatterns("/**");
}
}