IDEA項目搭建十一——添加攔截器、忽略URL大小寫、啟動事件


程序啟動時如果需要添加某些初始化代碼可以使用以下事件處理

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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM