SpringBoot攔截器

一般實(shí)現(xiàn)

  1. 定義一個攔截器類

MyInterceptor.java 實(shí)現(xiàn)HandlerInterceptor 接口

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;

@Component
public class MyInterceptor implements HandlerInterceptor {
    Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // TODO Auto-generated method stub
        //獲取session
        logger.info("---------------------開始進(jìn)入請求地址攔截----------------------------");
        //return true;
        HttpSession session = request.getSession(true);
        if (session.getAttribute("userId") == null) {
            logger.info("------:跳轉(zhuǎn)到login頁面周荐!");
//            response.reset();

            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = null;

            JSONObject res = new JSONObject();
            res.put("state", "0");
            res.put("msg", "login in first");
            res.put("output","");
            out = response.getWriter();
            out.append(res.toString());
            return false;
        } else {
            session.setAttribute("userId", session.getAttribute("userId"));
            return true;
        }
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub
        logger.info("--------------處理請求完成后視圖渲染之前的處理操作---------------");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
        logger.info("---------------視圖渲染之后的操作-------------------------0");
    }
}

定義一個WebConfig類,并將
WebConfig.java

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class WebConfig implements WebMvcConfigurer{
    @Resource
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/sensitiveword");//.excludePathPatterns("/login.html").excludePathPatterns("/*.min.js.*");
    }

}

這樣一個攔截器就實(shí)現(xiàn)了
HandlerInterceptor是一個接口,其中定義了三個default方法

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

WebMvcConfigurer也是一個接口璧疗,定義的方法都是default方法

import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;

public interface WebMvcConfigurer {
    default void configurePathMatch(PathMatchConfigurer configurer) {
    }
    //內(nèi)容協(xié)商配置
    default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    }

    default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    }

    default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    }
    //類型轉(zhuǎn)換器和格式化器
    default void addFormatters(FormatterRegistry registry) {
    }
    //添加攔截器
    default void addInterceptors(InterceptorRegistry registry) {
    }
    //添加靜態(tài)資源,重新定義靜態(tài)資源的路徑
    default void addResourceHandlers(ResourceHandlerRegistry registry) {
    }
    //添加跨域支持
    default void addCorsMappings(CorsRegistry registry) {
    }

    default void addViewControllers(ViewControllerRegistry registry) {
    }
    //配置視圖解析器
    default void configureViewResolvers(ViewResolverRegistry registry) {
    }

    default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    }

    default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
    }
    //配置消息轉(zhuǎn)換器
    default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }

    default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }

    @Nullable
    default Validator getValidator() {
        return null;
    }

    @Nullable
    default MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}

Servlet過濾器

  • Servlet過濾器提供過濾作用箕昭,能夠在調(diào)用前檢查Request對象,修改Request Header和Request內(nèi)容叶雹,在Servlet調(diào)用完成以后檢查Response對象,修改Response Header和Respones內(nèi)容
  • 可以串聯(lián)
  • 只有特定的URL才會觸發(fā)攔截器
public interface Filter {
        //Servlet過濾器的初始化方法换吧,Servlet容器創(chuàng)建Servlet過濾器實(shí)例后將調(diào)用這個方法折晦。在這個方法中可以讀取web.xml文件中Servlet過濾器的初始化參數(shù)
    public void init(FilterConfig filterConfig) throws ServletException;
    //完成實(shí)際的過濾操作,當(dāng)客戶請求訪問于過濾器關(guān)聯(lián)的URL時沾瓦,Servlet容器將先調(diào)用過濾器的doFilter方法满着。FilterChain參數(shù)用于訪問后續(xù)過濾器
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
         //Servlet容器在銷毀過濾器實(shí)例前調(diào)用該方法,這個方法中可以釋放Servlet過濾器占用的資源
    public void destroy();
}
public interface FilterConfig {
 //返回web.xml部署文件中定義的該過濾器的名稱
    String getFilterName();
 //返回調(diào)用者所處的servlet上下文
    ServletContext getServletContext();
//返回過濾器初始化參數(shù)值的字符串形式贯莺,當(dāng)參數(shù)不存在時风喇,返回nul1.name是初始化參數(shù)名
    String getInitParameter(String var1);
//以Enumeration形式返回過濾器所有初始化參數(shù)值,如果沒有初始化參數(shù)缕探,返回為空
    Enumeration<String> getInitParameterNames();
}

Servlet攔截過程

  1. 攔截器截獲客戶端請求
  2. 重新封裝ServletResponse响驴,在封裝后的ServletResponse中提供用戶自定義的輸出流
  3. 將請求后續(xù)傳遞
  4. Web組件響應(yīng)請求
  5. 獲取ServletRespones中的輸出流
  6. 將響應(yīng)內(nèi)容通過用戶自定義的輸出流寫入到緩沖流中
  7. 修改響應(yīng)內(nèi)容清空緩沖流輸出相應(yīng)內(nèi)容

對比

  • filter基于filter接口中的doFilter回調(diào)函數(shù),interceptor則基于Java本身的反射機(jī)制撕蔼;
  • filter是依賴于servlet容器的豁鲤,沒有servlet容器就無法回調(diào)doFilter方法,而interceptor與servlet無關(guān)鲸沮;
  • filter的過濾范圍比interceptor大琳骡,filter除了過濾請求外通過通配符可以保護(hù)頁面、圖片讼溺、文件等楣号,而interceptor只能過濾請求,只對action起作用怒坯,在action之前開始炫狱,在action完成后結(jié)束(如被攔截,不執(zhí)行action)剔猿;
  • filter的過濾一般在加載的時候在init方法聲明视译,而interceptor可以通過在xml聲明是guest請求還是user請求來辨別是否過濾;
  • interceptor可以訪問action上下文归敬、值棧里的對象酷含,而filter不能;
  • 在action的生命周期中汪茧,攔截器可以被多次調(diào)用椅亚,而過濾器只能在容器初始化時被調(diào)用一次。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舱污,一起剝皮案震驚了整個濱河市呀舔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扩灯,老刑警劉巖媚赖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件霜瘪,死亡現(xiàn)場離奇詭異,居然都是意外死亡省古,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門丧失,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豺妓,“玉大人,你說我怎么就攤上這事布讹×帐茫” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵描验,是天一觀的道長白嘁。 經(jīng)常有香客問我,道長膘流,這世上最難降的妖魔是什么絮缅? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮呼股,結(jié)果婚禮上耕魄,老公的妹妹穿的比我還像新娘。我一直安慰自己彭谁,他們只是感情好吸奴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缠局,像睡著了一般则奥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狭园,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天读处,我揣著相機(jī)與錄音,去河邊找鬼唱矛。 笑死档泽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的揖赴。 我是一名探鬼主播馆匿,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼燥滑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起铭拧,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤恃锉,失蹤者是張志新(化名)和其女友劉穎呕臂,沒想到半個月后破托,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歧蒋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年土砂,在試婚紗的時候發(fā)現(xiàn)自己被綠了谜洽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萝映。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡阐虚,死狀恐怖序臂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情实束,我是刑警寧澤奥秆,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站咸灿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏析显。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一谷异、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歹嘹,春花似錦、人聲如沸尺上。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至马绝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背掷邦。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抚岗,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓向抢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親件已。 傳聞我的和親對象是個殘疾皇子元暴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354