程序啟動時如果需要添加某些初始化代碼可以使用以下事件處理
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * 程序初始化事件 */ @Component public class ApplicationEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { // if (event instanceof ApplicationEnvironmentPreparedEvent) { // // 初始化環境變量 // }else if(event instanceof ApplicationPreparedEvent){ // // 初始化完成 // }else if (event instanceof ContextRefreshedEvent) { // // 應用刷新 // }else if (event instanceof ApplicationReadyEvent) { // // 應用已啟動完成 // }else if (event instanceof ContextStartedEvent) { // // 應用啟動,需要在代碼動態添加監聽器才可捕獲 // }else if (event instanceof ContextStoppedEvent) { // // 應用停止 // }else if (event instanceof ContextClosedEvent) { // // 應用關閉 // }else {} } }
過濾用戶登錄狀態驗證時普遍使用攔截器或過濾器spring boot 2.0使用以下方式
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 請求攔截器 * 參考資料:https://www.cnblogs.com/holly8/p/6178828.html * 普遍繼承HandlerInterceptorAdapter抽象類,其中多提供了一個異步攔截方法afterConcurrentHandlingStarted(),我們用不到所以直接實現基礎接口 * 調用順序:preHandler(可多個) -> Controller -> postHandler(可多個) -> model渲染-> afterCompletion(可多個) */ public class RequestInterceptor implements HandlerInterceptor { /** * Action執行前調用 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { try { System.out.println("調用攔截器"); //判斷用戶會話狀態 if (0 > 0) { System.out.println("攔截驗證-已登錄"); return true; } else { System.out.println("攔截驗證-未登錄"); //根據header標識判斷當前請求是否為Ajax請求 if (request.getHeader("x-requested-with") == null){ //如果不是Ajax請求則重定向 response.sendRedirect("/admin");//重定向回登錄頁 }else { //如果是Ajax則更改狀態碼通知前端 //response.sendError(580,"自定義錯誤");//如果想提示錯誤並根據配置文件自動跳轉到錯誤頁面,則使用sendError response.setStatus(401);//登錄異常(401)權限驗證不通過(403)如果只是改變狀態碼自己做后續處理,則使用setStatus /* 下面是直譯官方API文檔的內容: sendError(int sc):使用指定的狀態碼並清空緩沖,發送一個錯誤響應至客戶端。如果響應已經被提交,這個方法會拋出IllegalStateException。使用這個方法后,響應則應該被認為已被提交,且不應該再被進行寫操作了。 sendError(int sc, String msg):使用指定的狀態碼發送一個錯誤響應至客戶端。服務器默認會創建一個HTML格式的服務錯誤頁面作為響應結果,其中包含參數msg指定的文本信息,這個HTML頁面的內容類型為“text/html”, 保留cookies和其他未修改的響應頭信息。如果一個對應於傳入的錯誤碼的錯誤頁面已經在web.xml中聲明,那么這個聲明的錯誤頁面將會優先於建議的msg參數服務於客戶端。(ps:相比較上面的方法,我更傾向於前者。 使用上面的方法,可以通過定制不同狀態的響應結果顯示於客戶端,我們應該不想讓客戶端看到服務器創建出的簡單粗暴的頁面吧?) setStatus(int sc):設置響應的狀態碼。這個方法被用於當響應結果正常時(例如,狀態碼為SC_OK或SC_MOVED_TEMPORARTLY)設置響應狀態碼。如果發生錯誤,而且來訪者希望調用在web應用中定義的錯誤頁面作為顯示, 那么應該使用sendError方法代替之。使用setStatus方法之后,容器會清空緩沖並設置Location響應頭,保留cookies和其他響應頭信息。 總結:sendError適用於報錯且存在對應的報錯頁面配置作為輸出顯示的情況,而setStatus適用於正常響應的情況,僅僅可以改變響應狀態碼而已。 */ } return false; } } catch (Exception e) { e.printStackTrace(); return false; } } /** * Action執行后,View渲染前調用 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { } /** * View渲染后調用,整個流程執行結束調用 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { } }
注入攔截器到web中
import org.springframework.context.annotation.Configuration; import org.springframework.util.AntPathMatcher; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 配置類 * WebMvcConfigurerAdapter已被廢棄,官方推薦改用WebMvcConfigurer */ @Configuration public class MyInterceptorConfig implements WebMvcConfigurer { /** * 注入攔截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { //將攔截器注入進程序,可同時注入多個攔截器 //registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**"); /* 使用addPathPatterns增加攔截規則,使用excludePathPatterns排除攔截規則 /admin/**:代表http://域名/admin/** 攔截該目錄下的所有目錄及子目錄 /admin:代表http://域名/admin 僅攔截此形式訪問(無法攔截/admin/ 形式) /admin/*:代表http://域名/admin/* 攔截該目錄的所有下級目錄不包含子目錄(可以攔截/admin/ 形式) */ registry.addInterceptor(new RequestInterceptor()) .addPathPatterns("/admin/**") .excludePathPatterns("/admin") .excludePathPatterns("/admin/*") .excludePathPatterns("/admin/content/**"); } /** * 注入路徑匹配規則 */ @Override public void configurePathMatch(PathMatchConfigurer configurer) { //設置忽略請求URL的大小寫 AntPathMatcher matcher = new AntPathMatcher(); matcher.setCaseSensitive(false); configurer.setPathMatcher(matcher); //設置匹配規則 /* setUseSuffixPatternMatch : 設置是否是后綴模式匹配,如“/user”是否匹配/user.*,默認true即匹配 setUseTrailingSlashMatch : 設置是否自動后綴路徑模式匹配,如“/user”是否匹配“/user/”,默認true即匹配 */ configurer.setUseSuffixPatternMatch(false).setUseTrailingSlashMatch(true); } }
