Spring Cloud Feign使用ApacheHttpClient提交POST請求的問題


問題發生的背景:
Feign在默認情況下使用的是JDK原生的URLConnection發送HTTP請求,沒有連接池,但是對每個地址會保持一個長連接,即利用HTTP的persistence connection 。
我們可以用Apache的HTTP Client替換Feign原始的http client, 從而獲取連接池、超時時間等與性能息息相關的控制能力。Spring Cloud從Brixtion.SR5版本開始支持這種替換,
首先在項目中聲明Apache HTTP Client和feign-httpclient依賴:
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpasyncclient</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>8.17.0</version>
        </dependency>

  修改application.properties配置

feign.httpclient.enabled=true
FeignService Post接口

@FeignClient(name="eureka-client") public interface UserFeignService { @RequestMapping(value = "/user/update",method = RequestMethod.POST) String updateUser(@RequestBody User user); }

 



報錯如下:

  java.lang.IllegalArgumentException: MIME type may not contain reserved characters
    at org.apache.http.util.Args.check(Args.java:36) ~[httpcore-4.4.11.jar:4.4.11]
    at org.apache.http.entity.ContentType.create(ContentType.java:227) ~[httpcore-4.4.11.jar:4.4.11]
    at feign.httpclient.ApacheHttpClient.getContentType(ApacheHttpClient.java:159) ~[feign-httpclient-8.17.0.jar:8.17.0]
    at feign.httpclient.ApacheHttpClient.toHttpUriRequest(ApacheHttpClient.java:140) ~[feign-httpclient-8.17.0.jar:8.17.0]

 

  可以看出來是檢測Content-Type不合法報的異常,但在代碼中我們並沒有指定Content-Type,所以應該是使用了默認值。
  feign.httpclient.ApacheHttpClient

  

private ContentType getContentType(Request request) {
        ContentType contentType = ContentType.DEFAULT_TEXT;
        Iterator var3 = request.headers().entrySet().iterator();

        while(var3.hasNext()) {
            Entry<String, Collection<String>> entry = (Entry)var3.next();
            if(((String)entry.getKey()).equalsIgnoreCase("Content-Type")) {
                Collection values = (Collection)entry.getValue();
                if(values != null && !values.isEmpty()) {
                    contentType = ContentType.create((String)((Collection)entry.getValue()).iterator().next(), request.charset());
                    break;
                }
            }
        }
    return contentType; }
在ApacheHttpClient中看到默認設置的Content-Type是 ContentType.DEFAULT_TEXT,即 text/plain; charset=ISO-8859-1,其中包含分號,
也就導致了上面提到的異常。所以POST請求時我們需要指定Content-Type,修改下代碼:
import org.springframework.http.MediaType;
@FeignClient(name="eureka-client")
public interface UserFeignService {

    @RequestMapping(value = "/user/update",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
    String updateUser(@RequestBody User user);

}

通過給@RequestMapping設置consumes參數

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM