激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Spring Cloud中使用Feign,@RequestBody無法繼承的解決方案

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

2022-02-24 13:46phoebechen_gz Java教程

這篇文章主要介紹了Spring Cloud中使用Feign,@RequestBody無法繼承的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

使用Feign,@RequestBody無法繼承的問題

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

?
1
2
3
4
5
6
7
@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);
}

實現(xiàn)類

?
1
2
3
4
5
6
@Override
   public boolean updateUser(UserDTO user)
   {  
       LOGGER.info("===updateUser, id = " + user.getId() + " ,name= " + user.getUsername());
       return false;
   }

執(zhí)行單元測試,發(fā)現(xiàn)沒有獲取到預(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類進(jìn)行入?yún)ⅰ⒊鰠⒌慕馕觥R韵路椒ǜ鶕?jù)參數(shù)是否有@RequestBody注解判斷是否進(jìn)行消息體的轉(zhuǎn)換。

?
1
2
3
4
@Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestBody.class);
    }

解決方案

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

?
1
2
3
4
5
6
7
8
9
@Override
   public boolean supportsParameter(MethodParameter parameter)
   {
       //springcloud的接口入?yún)]有寫@RequestBody,并且是自定義類型對象 也按JSON解析
       if (AnnotatedElementUtils.hasAnnotation(parameter.getContainingClass(), FeignClient.class) && isCustomizedType(parameter.getParameterType())) {
           return true;
       }
       return super.supportsParameter(parameter);
   }

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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ù)的實現(xiàn)類即可去掉@RequestBody注解。

使用feign遇到的問題

spring cloud 使用feign 項目的搭建 在這里就不寫了,本文主要講解在使用過程中遇到的問題以及解決辦法

1、示例

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

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

@PostMapping 否則項目啟動會報

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

2、首次訪問超時問題

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

而首次請求往往會比較慢(因為Spring的懶加載機(jī)制,要實例化一些類),這個響應(yīng)時間可能就大于1秒了。

解決方法:

<1:配置Hystrix的超時時間改為5秒

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

<2:禁用Hystrix的超時時間

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

<3:禁用feign的hystrix 功能

?
1
feign.hystrix.enabled: false

注:個人推薦 第一 或者第二種 方法

3、FeignClient接口中

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

spring cloud feign 使用 Apache HttpClient

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ApacheHttpClient.class
  private ContentType getContentType(Request request) {
    ContentType contentType = ContentType.DEFAULT_TEXT;
    for (Map.Entry<String, Collection<String>> entry : request.headers().entrySet())
    // 這里會判斷 如果沒有指定 Content-Type 屬性 就使用上面默認(rèn)的 text/plain; charset=ISO-8859-1
    // 問題出在默認(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;
  }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ContentType.class
   public static ContentType create(final String mimeType, final Charset charset) {
        final String normalizedMimeType = Args.notBlank(mimeType, "MIME type").toLowerCase(Locale.ROOT);
 // 問題在這 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)了 分號 導(dǎo)致檢驗沒有通過
            if (ch == '"' || ch == ',' || ch == ';') {
                return false;
            }
        }
        return true;
    }

解決辦法 :

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

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

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/phoebechen_gz/article/details/82500904

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 最近日本电影hd免费观看 | 中文国产在线视频 | 亚洲涩涩图 | 久草成人在线 | 91麻豆精品国产91久久久更新资源速度超快 | 精品久久久久久久久久久久包黑料 | 在线观看国产一区二区 | 黄色网址在线播放 | 久久精热 | 成人免费在线视频 | 日韩精品久久久久久久电影99爱 | 免费国产一级淫片 | 老师你怎么会在这第2季出现 | 成人做爽爽爽爽免费国产软件 | 欧美视频99 | 国产欧美日韩一区二区三区四区 | 黄色免费视频观看 | 国产孕妇孕交大片孕 | 色多多视频导航 | 一区二区免费网站 | 成人欧美日韩一区二区三区 | 爽毛片| 羞羞网站在线观看入口免费 | 在线男人天堂 | 精品亚洲va在线va天堂资源站 | 欧美hdfree性xxxx | 成人在线观看小视频 | 亚洲一区二区三区在线播放 | chinese军人gay呻吟 | www.99久久久 | 色爽爽爽| 少妇的肉体的满足毛片 | 国内免费视频成人精品 | 青青草成人免费视频在线 | 91短视频在线 | 成人爽a毛片免费啪啪红桃视频 | 九草网| 国产成人强伦免费视频网站 | 欧美视频一二三区 | 国产电影精品久久 | 成人黄视频在线观看 |