偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

SpringBoot中的攔截器江湖

開發(fā) 前端
很多小伙伴在工作中遇到攔截需求就無腦寫HandlerInterceptor,結(jié)果被復(fù)雜場景搞得鼻青臉腫。作為一名有多年開發(fā)經(jīng)驗(yàn)的程序員,今天領(lǐng)大家到SpringBoot的山頭認(rèn)認(rèn)6把交椅。

前言

很多小伙伴在工作中遇到攔截需求就無腦寫HandlerInterceptor,結(jié)果被復(fù)雜場景搞得鼻青臉腫。

作為一名有多年開發(fā)經(jīng)驗(yàn)的程序員,今天領(lǐng)大家到SpringBoot的山頭認(rèn)認(rèn)6把交椅:

圖片圖片

這篇文章以梁山為背景的介紹SpringBoot中的攔截器,可能更通俗易懂。

希望對(duì)你會(huì)有所幫助,記得點(diǎn)贊和收藏。

第一把交椅:Filter

Filter是梁山中的總寨主。

典型戰(zhàn)斗場面:全局鑒權(quán)/接口耗時(shí)統(tǒng)計(jì)

@WebFilter("/*") 
public class CostFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
        long start = System.currentTimeMillis();
        chain.doFilter(req, res); // 放行江湖令箭
        System.out.println("接口耗時(shí):"+(System.currentTimeMillis()-start)+"ms");
    }
}

起義緣由:必須是最高寨主,因?yàn)樗赟ervlet容器滾刀肉層面出手。想當(dāng)年有個(gè)兄弟在Filter里調(diào)用Spring Bean,結(jié)果NPE錯(cuò)殺千人(要用WebApplicationContextUtils拿Bean才是正解)

第二把交椅:HandlerInterceptor

HandlerInterceptor是梁山中的二當(dāng)家。

必殺場景:接口權(quán)限驗(yàn)證/請(qǐng)求參數(shù)自動(dòng)裝填

public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("X-Token");
        if(!"vip666".equals(token)){
            response.setStatus(403);
            returnfalse; // 關(guān)門放狗
        }
        returntrue;
    }
}

// 衙門張貼告示
@Configuration
publicclass WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/login");
    }
}

二當(dāng)家的雷區(qū)

  1. postHandle里修改了Response但內(nèi)容已提交(注意response.isCommitted()判斷)
  2. 攔截資源請(qǐng)求要配置靜態(tài)路徑排出(例如/exclude/**)
  3. 多攔截器順序要調(diào)準(zhǔn)確(Order值越小越早執(zhí)行)

第三把交椅:AOP攔截器

AOP是梁山中的軍師智多星。

運(yùn)籌帷幄場景:服務(wù)層方法緩存/事務(wù)管理

@Aspect
@Component
public class CacheAspect {
    @Around("@annotation(com.example.anno.Cacheable)")
    public Object aroundCache(ProceedingJoinPoint jp) {
        String cacheKey = buildKey(jp);
        Object cacheVal = redisTemplate.opsForValue().get(cacheKey);
        if(cacheVal != null) return cacheVal;
        
        Object result = jp.proceed();
        redisTemplate.opsForValue().set(cacheKey, result, 5, TimeUnit.MINUTES);
        return result;
    }
}

軍師錦囊

  • 只可攔截Spring管理的Bean(new的對(duì)象攔截不了)
  • 與Transactional注解的順序要注意(建議AOP切面Order大于事務(wù)切面)
  • 自定義注解要寫在接口方法上才生效(要是實(shí)現(xiàn)類方法需要用@within)

第四把交椅:RestTemplate攔截器

RestTemplate是梁山中的水軍頭領(lǐng)。

遠(yuǎn)程戰(zhàn)事:統(tǒng)一添加請(qǐng)求頭/加密請(qǐng)求參數(shù)

public class TraceInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) {
        request.getHeaders().add("X-TraceId", UUID.randomUUID().toString());
        return execution.execute(request, body);
    }
}

// 注冊(cè)水軍
@Bean
public RestTemplate restTemplate() {
    RestTemplate rt = new RestTemplate();
    rt.getInterceptors().add(new TraceInterceptor());
    return rt;
}

總督黑歷史

  1. 編碼問題:body若是字符串需要自行轉(zhuǎn)字節(jié)數(shù)組(避免亂碼)
  2. 多次攔截:攔截器按添加順序執(zhí)行(第一個(gè)最后執(zhí)行)
  3. 訪問HTTPS需要額外配置SSL(記得補(bǔ)上SSLContext)

第五把交椅:Feign攔截器

Feign攔截器是梁山中的外交使節(jié)。

出使外國:統(tǒng)一簽名計(jì)算/Header透傳

public class FeignAuthInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        template.header("Authorization", "Bearer " + SecurityContext.getToken());
    }
}

// 締結(jié)合約
@Configuration
publicclass FeignConfig {
    @Bean
    public FeignAuthInterceptor feignAuthInterceptor() {
        returnnew FeignAuthInterceptor();
    }
}

使節(jié)燙手山芋

  • GET請(qǐng)求Body丟失問題(要自己特殊處理)
  • Form表單參數(shù)要手動(dòng)編碼(使用feign-form擴(kuò)展)
  • Path參數(shù)需要Expression表達(dá)式解析(動(dòng)態(tài)值要用@Param注明)

第六把交椅:WebFilter

WebFilter是梁山中的特種兵。

閃電戰(zhàn)場景:響應(yīng)式編程統(tǒng)一編碼/跨域處理

@Component
public class CorsWebFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        return chain.filter(exchange);
    }
}

作戰(zhàn)條件

  • 必須在WebFlux環(huán)境下(傳統(tǒng)MVC無效)
  • 響應(yīng)式編程模式(函數(shù)式聲明)
  • 非阻塞管道(異步要配合Mono/Flux)

各派武功排行榜

門派

攻擊范圍

招式復(fù)雜度

內(nèi)力消耗

首選戰(zhàn)場

Filter

全局最外層

★★☆☆☆

安全校驗(yàn)/日志記錄

Handler

MVC控制器層

★★★☆☆

權(quán)限控制

AOP

業(yè)務(wù)方法級(jí)

★★★★☆

緩存/事務(wù)

RestTemplate

HTTP客戶端

★★★☆☆

服務(wù)間調(diào)用

Feign

聲明式客戶端

★★★★☆

微服務(wù)通信

WebFilter

響應(yīng)式全鏈路

★★★★★

極高

WebFlux應(yīng)用

武林秘笈

1. 順序就是力量

Filter -> Interceptor -> AOP ,越早攔截越省力(但別在Filter里做業(yè)務(wù))

2. 量力而行選兵器

  • 簡單鑒權(quán)用HandlerInterceptor
  • 方法級(jí)管控上AOP
  • 微服務(wù)用FeignInterceptor

3. 性能損耗要監(jiān)控

用Arthas監(jiān)控?cái)r截鏈路耗時(shí),避免攔截器連環(huán)奪命c(diǎn)all

# 查看HandlerInterceptor耗時(shí)
trace *.preHandle '#cost>10'
 
# 診斷AOP切面
watch com.example.aop.*Aspect * '{params,returnObj}' -x 3

最后送給各位江湖兒女一句話:

攔截是門藝術(shù),別讓好刀砍了自己人!

責(zé)任編輯:武曉燕 來源: 蘇三說技術(shù)
相關(guān)推薦

2020-03-25 17:55:30

SpringBoot攔截器Java

2023-09-05 08:58:07

2025-01-02 10:10:51

2009-06-24 16:00:00

2009-09-27 17:37:32

Hibernate攔截

2025-02-28 08:14:53

2023-09-15 11:26:16

2024-05-06 00:00:00

C#工具代碼

2011-05-16 10:14:11

Hibernate

2011-11-21 14:21:26

SpringMVCJava框架

2009-07-08 17:02:11

JDK實(shí)現(xiàn)調(diào)用攔截器

2021-07-19 05:48:30

springboot 攔截器項(xiàng)目

2024-05-13 09:32:06

攔截器HTTP中間件

2009-06-25 15:54:42

Struts2教程攔截器

2021-11-03 17:04:11

攔截器操作Servlet

2009-06-25 15:59:21

Struts2教程攔截器

2012-02-03 13:27:16

2009-02-04 14:19:38

2009-02-04 14:45:06

2009-06-04 08:01:25

Struts2攔截器原理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)