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

Spring Cloud中使用Feign,@RequestBody無(wú)法繼承的解決方案

 更新時(shí)間:2021年10月22日 08:57:54   作者:phoebechen_gz  
這篇文章主要介紹了Spring Cloud中使用Feign,@RequestBody無(wú)法繼承的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

使用Feign,@RequestBody無(wú)法繼承的問(wèn)題

根據(jù)官網(wǎng)FeignClient的例子,編寫(xiě)一個(gè)簡(jiǎn)單的updateUser接口,定義如下

@RequestMapping("/user")
public interface UserService {
    @RequestMapping(value = "/{userId}", method = RequestMethod.GET)
    UserDTO findUserById(@PathVariable("userId") Integer userId);
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    boolean updateUser(@RequestBody UserDTO user);
}

實(shí)現(xiàn)類(lèi)

 @Override
    public boolean updateUser(UserDTO user)
    {   
        LOGGER.info("===updateUser, id = " + user.getId() + " ,name= " + user.getUsername());
        return false;
    }

執(zhí)行單元測(cè)試,發(fā)現(xiàn)沒(méi)有獲取到預(yù)期的輸入?yún)?shù)

2018-09-07 15:35:38,558 [http-nio-8091-exec-5] INFO [com.springboot.user.controller.UserController] {} - ===updateUser, id = null ,name= null

原因分析

SpringMVC中使用RequestResponseBodyMethodProcessor類(lèi)進(jìn)行入?yún)?、出參的解析。以下方法根?jù)參數(shù)是否有@RequestBody注解判斷是否進(jìn)行消息體的轉(zhuǎn)換。

@Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestBody.class);
    }

解決方案

既然MVC使用RequestResponseBodyMethodProcessor進(jìn)行參數(shù)解析,可以實(shí)現(xiàn)一個(gè)定制化的Processor,修改supportParameter的判斷方法。

 @Override
    public boolean supportsParameter(MethodParameter parameter)
    {
        //springcloud的接口入?yún)](méi)有寫(xiě)@RequestBody,并且是自定義類(lèi)型對(duì)象 也按JSON解析
        if (AnnotatedElementUtils.hasAnnotation(parameter.getContainingClass(), FeignClient.class) && isCustomizedType(parameter.getParameterType())) {
            return true;
        }
        return super.supportsParameter(parameter);
    }

此處的判斷邏輯可以根據(jù)實(shí)際框架進(jìn)行定義,目的是判斷到為Spring Cloud定義的接口,并且是自定義對(duì)象時(shí),使用@RequestBody相同的內(nèi)容轉(zhuǎn)換器。

實(shí)現(xiàn)定制化的Processor后,還需要讓自定義的配置生效,有兩種方案可選:

  • 直接替換RequestResponseBodyMethodProcessor,在SpringBoot下需要自定義RequestMappingHandlerAdapter。
  • 實(shí)現(xiàn)WebMvcConfigurer中的addArgumentResolvers接口

這里采用較為簡(jiǎn)單的第二種方式,初始化時(shí)的消息轉(zhuǎn)換器根據(jù)需要進(jìn)行加載:

public class XXXWebMvcConfig implements WebMvcConfigurer
{
@Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers)
    {
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        stringHttpMessageConverter.setWriteAcceptCharset(false);
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(5);
        messageConverters.add(new ByteArrayHttpMessageConverter());
        messageConverters.add(stringHttpMessageConverter);
        messageConverters.add(new SourceHttpMessageConverter<>());
        messageConverters.add(new AllEncompassingFormHttpMessageConverter());
        CustomizedMappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new CustomizedMappingJackson2HttpMessageConverter();
        jackson2HttpMessageConverter.setObjectMapper(defaultObjectMapper());
        messageConverters.add(jackson2HttpMessageConverter);
        ViomiMvcRequestResponseBodyMethodProcessor resolver = new ViomiMvcRequestResponseBodyMethodProcessor(messageConverters);
        resolvers.add(resolver);
    }

修改完成后,微服務(wù)的實(shí)現(xiàn)類(lèi)即可去掉@RequestBody注解。

使用feign遇到的問(wèn)題

spring cloud 使用feign 項(xiàng)目的搭建 在這里就不寫(xiě)了,本文主要講解在使用過(guò)程中遇到的問(wèn)題以及解決辦法

1、示例

@RequestMapping(value = "/generate/password", method = RequestMethod.POST)
KeyResponse generatePassword(@RequestBody String passwordSeed);

在這里 只能使用 @RequestMapping(value = "/generate/password", method = RequestMethod.POST) 注解 不能使用

@PostMapping 否則項(xiàng)目啟動(dòng)會(huì)報(bào)

Caused by: java.lang.IllegalStateException: Method generatePassword not annotated with HTTP method type (ex. GET, POST) 異常

2、首次訪問(wèn)超時(shí)問(wèn)題

原因:Hystrix默認(rèn)的超時(shí)時(shí)間是1秒,如果超過(guò)這個(gè)時(shí)間尚未響應(yīng),將會(huì)進(jìn)入fallback代碼。

而首次請(qǐng)求往往會(huì)比較慢(因?yàn)镾pring的懶加載機(jī)制,要實(shí)例化一些類(lèi)),這個(gè)響應(yīng)時(shí)間可能就大于1秒了。

解決方法:

<1:配置Hystrix的超時(shí)時(shí)間改為5秒

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000

<2:禁用Hystrix的超時(shí)時(shí)間

hystrix.command.default.execution.timeout.enabled: false

<3:禁用feign的hystrix 功能

feign.hystrix.enabled: false

注:個(gè)人推薦 第一 或者第二種 方法

3、FeignClient接口中

如果使用到@PathVariable,必須指定其value

spring cloud feign 使用 Apache HttpClient

問(wèn)題:1 沒(méi)有指定 Content-Type 是情況下 會(huì)出現(xiàn)如下異常 ? 這里很納悶?

Caused by: java.lang.IllegalArgumentException: MIME type may not contain reserved characters

在這里有興趣的朋友可以去研究下源碼

ApacheHttpClient.class 
  private ContentType getContentType(Request request) {
    ContentType contentType = ContentType.DEFAULT_TEXT;
    for (Map.Entry<String, Collection<String>> entry : request.headers().entrySet())
    // 這里會(huì)判斷 如果沒(méi)有指定 Content-Type 屬性 就使用上面默認(rèn)的 text/plain; charset=ISO-8859-1
    // 問(wèn)題出在默認(rèn)的 contentType : 格式 text/plain; charset=ISO-8859-1 
    // 轉(zhuǎn)到 ContentType.create(entry.getValue().iterator().next(), request.charset()); 方法中看
    if (entry.getKey().equalsIgnoreCase("Content-Type")) {
      Collection values = entry.getValue();
      if (values != null && !values.isEmpty()) {
        contentType = ContentType.create(entry.getValue().iterator().next(), request.charset());
        break;
      }
    }
    return contentType;
  }
ContentType.class
   public static ContentType create(final String mimeType, final Charset charset) {
        final String normalizedMimeType = Args.notBlank(mimeType, "MIME type").toLowerCase(Locale.ROOT);
 // 問(wèn)題在這 check  中 valid f方法中
        Args.check(valid(normalizedMimeType), "MIME type may not contain reserved characters");
        return new ContentType(normalizedMimeType, charset);
    }
   private static boolean valid(final String s) {
        for (int i = 0; i < s.length(); i++) {
            final char ch = s.charAt(i);
     // 這里 在上面 text/plain;charset=UTF-8 中出現(xiàn)了 分號(hào) 導(dǎo)致檢驗(yàn)沒(méi)有通過(guò) 
            if (ch == '"' || ch == ',' || ch == ';') {
                return false;
            }
        }
        return true;
    }

解決辦法 :

@RequestMapping(value = "/generate/password", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)

注解中指定: Content-Type 即 指定 consumes 的屬性值 : 這里 consumes 屬性的值在這不做具體講解,有興趣的可以去研究下

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot+Vue+Redis實(shí)現(xiàn)單點(diǎn)登錄(一處登錄另一處退出登錄)

    SpringBoot+Vue+Redis實(shí)現(xiàn)單點(diǎn)登錄(一處登錄另一處退出登錄)

    小編接到一個(gè)需求,需要實(shí)現(xiàn)用戶(hù)在瀏覽器登錄后,跳轉(zhuǎn)到其他頁(yè)面,當(dāng)用戶(hù)在其它地方又登錄時(shí),前面用戶(hù)登錄的頁(yè)面退出登錄,這篇文章主要介紹了SpringBoot+Vue+Redis實(shí)現(xiàn)單點(diǎn)登錄,需要的朋友可以參考下
    2019-12-12
  • 簡(jiǎn)單說(shuō)說(shuō)Java SE、Java EE、Java ME三者之間的區(qū)別

    簡(jiǎn)單說(shuō)說(shuō)Java SE、Java EE、Java ME三者之間的區(qū)別

    本篇文章小編就為大家簡(jiǎn)單說(shuō)說(shuō)Java SE、Java EE、Java ME三者之間的區(qū)別。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-10-10
  • Java使用lambda自定義Arrays.sort排序規(guī)則說(shuō)明

    Java使用lambda自定義Arrays.sort排序規(guī)則說(shuō)明

    這篇文章主要介紹了Java使用lambda自定義Arrays.sort排序規(guī)則說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • mybatis 加載配置文件的方法(兩種方式)

    mybatis 加載配置文件的方法(兩種方式)

    這篇文章主要介紹了mybatis 加載配置文件的方法,通過(guò)實(shí)例代碼給大家介紹了mybatis 加載配置文件的兩種方式,需要的朋友可以參考下
    2017-12-12
  • springboot運(yùn)行時(shí)新增/更新外部接口的實(shí)現(xiàn)方法

    springboot運(yùn)行時(shí)新增/更新外部接口的實(shí)現(xiàn)方法

    這篇文章主要介紹了springboot運(yùn)行時(shí)新增/更新外部接口的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • java隨機(jī)生成10位數(shù)的字符串ID

    java隨機(jī)生成10位數(shù)的字符串ID

    這篇文章主要為大家詳細(xì)介紹了java隨機(jī)生成10位數(shù)字符串ID的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • JAVA中的日期LocalDate類(lèi)詳細(xì)用法講解

    JAVA中的日期LocalDate類(lèi)詳細(xì)用法講解

    Java中存在一個(gè)日歷表示法的類(lèi)庫(kù),LocalDate類(lèi),如果只想要指定的年月日就可以用這個(gè)LocalDate類(lèi),下面這篇文章主要給大家介紹了關(guān)于JAVA中日期LocalDate類(lèi)詳細(xì)用法講解的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • Java中自己如何實(shí)現(xiàn)log2(N)

    Java中自己如何實(shí)現(xiàn)log2(N)

    這篇文章主要介紹了Java中自己實(shí)現(xiàn)log2(N)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java list利用遍歷進(jìn)行刪除操作3種方法解析

    Java list利用遍歷進(jìn)行刪除操作3種方法解析

    這篇文章主要介紹了Java list利用遍歷進(jìn)行刪除操作3種方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Java設(shè)計(jì)模式之模板方法模式Template Method Pattern詳解

    Java設(shè)計(jì)模式之模板方法模式Template Method Pattern詳解

    在我們實(shí)際開(kāi)發(fā)中,如果一個(gè)方法極其復(fù)雜時(shí),如果我們將所有的邏輯寫(xiě)在一個(gè)方法中,那維護(hù)起來(lái)就很困難,要替換某些步驟時(shí)都要重新寫(xiě),這樣代碼的擴(kuò)展性就很差,當(dāng)遇到這種情況就要考慮今天的主角——模板方法模式
    2022-11-11

最新評(píng)論

迁安市| 沁源县| 四平市| 宝坻区| 松溪县| 剑川县| 土默特左旗| 中江县| 惠东县| 合水县| 万山特区| 石河子市| 吴忠市| 禄劝| 和田市| 梧州市| 漳平市| 吴堡县| 白河县| 丰县| 淳安县| 桂东县| 洛扎县| 卢氏县| 桦甸市| 阿坝| 周宁县| 城市| 明光市| 福建省| 永川市| 贺兰县| 邵东县| 鞍山市| 梅河口市| 双桥区| 洛扎县| 灵山县| 枣阳市| 大丰市| 衡阳市|