最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Feign利用自定義注解實現(xiàn)路徑轉(zhuǎn)義詳解

 更新時間:2022年06月28日 09:32:07   作者:初夏的陽光丶  
這篇文章主要講解一下如何通過注解實現(xiàn)對路由中的路徑進行自定義編碼,文中的示例代碼講解詳細,對我們學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下

背景

近期由于項目中需要,所以需要通過Feign封裝一個對Harbor操作的sdk信息。

在調(diào)用的過程中發(fā)現(xiàn),當(dāng)請求參數(shù)中帶有"/"時,F(xiàn)eign默認會將"/"當(dāng)成路徑去解析,而不是當(dāng)成完整的一個參數(shù)解析,實例如下

請求路徑為:api/v2.0/projects/{projectName}/repositories

注解參數(shù)為:@PathVariable("projectName")

正常請求為:api/v2.0/projects/test/repositories

異常路徑為:api/v2.0/projects/test/pro/repositories

相信細心的同學(xué)已經(jīng)發(fā)現(xiàn)上面的差異了,正常的{projectName}中對應(yīng)的值為test,而異常的卻對應(yīng)為test/pro,所以當(dāng)異常的請求打到harbor的機器時,被解析為api/v2.0/projects/test/pro/repositories,所以會直接返回404

以上就是背景了,所以接下來我們討論一下解決方案

解決方案

首先我們知道springboot中默認是帶有幾種注釋參數(shù)處理器的

@MatrixVariableParameterProcessor
@PathVariableParameterProcessor
@QueryMapParameterProcessor
@RequestHeaderParameterProcessor
@RequestParamParameterProcessor
@RequestPartParameterProcessor

因為我們的請求參數(shù)是在路徑中的,所以默認我們會使用@PathVariableParameterProcessor來標(biāo)識路徑參數(shù),而我們需要轉(zhuǎn)義的參數(shù)其實也是在路徑中,所以我們先來看一下@PathVariableParameterProcessor是如何實現(xiàn)的

public boolean processArgument(AnnotatedParameterProcessor.AnnotatedParameterContext context, Annotation annotation, Method method) {
        String name = ((PathVariable)ANNOTATION.cast(annotation)).value();
        Util.checkState(Util.emptyToNull(name) != null, "PathVariable annotation was empty on param %s.", new Object[]{context.getParameterIndex()});
        context.setParameterName(name);
        MethodMetadata data = context.getMethodMetadata();
        String varName = '{' + name + '}';
        if (!data.template().url().contains(varName) && !this.searchMapValues(data.template().queries(), varName) && !this.searchMapValues(data.template().headers(), varName)) {
            data.formParams().add(name);
        }
        return true;
    }

其實在源碼中,springboot并沒有做什么神器的事情,就是獲取使用了PathVariable注解的參數(shù),然后再將其添加到fromParams中就可以。

看到這里我們是不是可以想到,既然在這里我們可以拿到對應(yīng)的參數(shù)了,那想做什么事情不都是由我們自己來決定了,接下來說干就干,

首先我們聲明一個屬于自己的注解,

import org.springframework.core.annotation.AliasFor;

import java.lang.annotation.*;

/**
  * @CreateAt: 2022/6/11 0:46
 * @ModifyAt: 2022/6/11 0:46
 * @Version 1.0
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SlashPathVariable {

    /**
     * Alias for {@link #name}.
     */
    @AliasFor("name")
    String value() default "";

    /**
     * The name of the path variable to bind to.
     * @since 4.3.3
     */
    @AliasFor("value")
    String name() default "";

    /**
     * Whether the path variable is required.
     * <p>Defaults to {@code true}, leading to an exception being thrown if the path
     * variable is missing in the incoming request. Switch this to {@code false} if
     * you prefer a {@code null} or Java 8 {@code java.util.Optional} in this case.
     * e.g. on a {@code ModelAttribute} method which serves for different requests.
     * @since 4.3.3
     */
    boolean required() default true;
}

聲明完注解后,我們就需要來自定義自己的參數(shù)解析器了,首先繼承AnnotatedParameterProcessor

import feign.MethodMetadata;
import feign.Util;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.web.bind.annotation.PathVariable;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @CreateAt: 2022/6/11 0:36
 * @ModifyAt: 2022/6/11 0:36
 * @Version 1.0
 */
public class SlashPathVariableParameterProcessor implements AnnotatedParameterProcessor {

    private  static  final Class<SlashPathVariable> ANNOTATION=SlashPathVariable.class;
    @Override
    public Class<? extends Annotation> getAnnotationType() {
        return (Class<? extends Annotation>) ANNOTATION;
    }

    @Override
    public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
        MethodMetadata data = context.getMethodMetadata();
        String name = ANNOTATION.cast(annotation).value();
        Util.checkState(Util.emptyToNull(name) != null, "SlashPathVariable annotation was empty on param %s.", new Object[]{context.getParameterIndex()});
        context.setParameterName(name);
        data.indexToExpander().put(context.getParameterIndex(),this::expandMap);
        return true;
    }

    private String expandMap(Object object) {
        String encode = URLEncoder.encode(URLEncoder.encode(object.toString(), Charset.defaultCharset()), Charset.defaultCharset());
        return encode;
    }
}

可以看到上面的代碼,我們獲取到自定義注解的參數(shù)后,將當(dāng)前參數(shù)添加打Param后,并且為當(dāng)前參數(shù)指定自定義的編碼格式。

最后,我們再通過Bean的形式將對應(yīng)的注解添加到容器中

import feign.Contract;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @CreateAt: 2022/6/11 0:48
 * @ModifyAt: 2022/6/11 0:48
 * @Version 1.0
 */
@Component
public class SlashBean {

    @Bean
    public Contract feignContract(){
        List<AnnotatedParameterProcessor> processors=new ArrayList<>();
        processors.add(new SlashPathVariableParameterProcessor());
        return new SpringMvcContract(processors);
    }
}

最后我們將上面的參數(shù)注解PathVariable換成我們自定義的@SlashPathVariable,就大功告成了

最后

通過以上的形式進行注入的話,會注入到Spring全局,所以在使用的過程中需要考慮是否符合場景

以上就是Feign利用自定義注解實現(xiàn)路徑的轉(zhuǎn)義詳解的詳細內(nèi)容,更多關(guān)于Feign路徑的轉(zhuǎn)義的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java并發(fā)編程工具類JUC之ArrayBlockingQueue

    java并發(fā)編程工具類JUC之ArrayBlockingQueue

    類ArrayBlockingQueue是BlockingQueue接口的實現(xiàn)類,它是有界的阻塞隊列,內(nèi)部使用數(shù)組存儲隊列元素,通過代碼給大家說明如何初始化一個ArrayBlockingQueue,并向其中添加一個對象,對java并發(fā)編程工具類ArrayBlockingQueue相關(guān)知識感興趣的朋友一起看看吧
    2021-05-05
  • SpringBoot中使用@scheduled定時執(zhí)行任務(wù)的坑

    SpringBoot中使用@scheduled定時執(zhí)行任務(wù)的坑

    本文主要介紹了SpringBoot中使用@scheduled定時執(zhí)行任務(wù)的坑,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 200行Java代碼如何實現(xiàn)依賴注入框架詳解

    200行Java代碼如何實現(xiàn)依賴注入框架詳解

    依賴注入對大家來說應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于利用200行Java代碼如何實現(xiàn)依賴注入框架的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • spring boot的健康檢查HealthIndicators實戰(zhàn)

    spring boot的健康檢查HealthIndicators實戰(zhàn)

    這篇文章主要介紹了spring boot的健康檢查HealthIndicators實戰(zhàn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 淺談Storm在zookeeper上的目錄結(jié)構(gòu)

    淺談Storm在zookeeper上的目錄結(jié)構(gòu)

    這篇文章主要介紹了淺談Storm在zookeeper上的目錄結(jié)構(gòu)的相關(guān)內(nèi)容,涉及storm使用zookeeper的操作以及詳細結(jié)構(gòu)圖,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • Java類加載器層次結(jié)構(gòu)原理解析

    Java類加載器層次結(jié)構(gòu)原理解析

    這篇文章主要介紹了Java類加載器層次結(jié)構(gòu)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • Spring Boot實現(xiàn)通用的接口參數(shù)校驗

    Spring Boot實現(xiàn)通用的接口參數(shù)校驗

    本文介紹基于 Spring Boot 和 JDK8 編寫一個 AOP ,結(jié)合自定義注解實現(xiàn)通用的接口參數(shù)校驗。具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Lucene fnm索引文件格式源碼解析

    Lucene fnm索引文件格式源碼解析

    這篇文章主要為大家介紹了Lucene fnm索引文件格式源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Intellij IDEA 2019 最新亂碼問題及解決必殺技(必看篇)

    Intellij IDEA 2019 最新亂碼問題及解決必殺技(必看篇)

    大家在使用Intellij IDEA 的時候會經(jīng)常遇到各種亂碼問題,今天小編給大家分享一些關(guān)于Intellij IDEA 2019 最新亂碼問題及解決必殺技,感興趣的朋友跟隨小編一起看看吧
    2020-04-04
  • SpringBoot工程搭建打包、啟動jar包和war包的教程圖文詳解

    SpringBoot工程搭建打包、啟動jar包和war包的教程圖文詳解

    這篇文章主要介紹了SpringBoot工程搭建打包、啟動jar包和war包的教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09

最新評論

清徐县| 都匀市| 彩票| 佛冈县| 临颍县| 新兴县| 台江县| 当雄县| 五大连池市| 桂阳县| 曲阜市| 兴仁县| 永吉县| 巨野县| 贺兰县| 防城港市| 石家庄市| 潼南县| 个旧市| 响水县| 望谟县| 元阳县| 广河县| 南和县| 清流县| 东兴市| 甘孜| 神池县| 吴江市| 中山市| 荣成市| 彩票| 霍林郭勒市| 醴陵市| 凌云县| 岳阳县| 旬邑县| 泽州县| 涿鹿县| 阜阳市| 达拉特旗|