2020年10月11日 星期日

[Java] Invalid HTTP method: PATCH

最近系統需要使用 Netty4,所以把衝突的 Netty3 拆掉,然後就出現了例外。

pom.xml

<dependency>
   <groupId>com.ning</groupId>
   <artifactId>async-http-client</artifactId>
   <version>1.9.40</version>
   <exclusions>
      <exclusion>
         <groupId>io.netty</groupId>
         <artifactId>netty</artifactId>
      </exclusion>
   </exclusions>
</dependency>

client

Request request = new RequestBuilder("POST")
      .setUrl(url)
      .setBody(body)
      .setHeader("Content-Type", contentType)
      .setRequestTimeout(timeout)
      .build();
Future&lg4;Response> future = client.executeRequest(request);

console log

[AsyncHttpClient-Callback] DEBUG c.n.h.c.p.jdk.JDKAsyncHttpProvider - Invalid HTTP method: PATCH
java.net.ProtocolException: Invalid HTTP method: PATCH
        at java.net.HttpURLConnection.setRequestMethod(HttpURLConnection.java:440)
        at sun.net.www.protocol.http.HttpURLConnection.setRequestMethod(HttpURLConnection.java:553)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestMethod(HttpsURLConnectionImpl.java:388)
        at com.ning.http.client.providers.jdk.JDKAsyncHttpProvider$AsyncHttpUrlConnection.configure(JDKAsyncHttpProvider.java:530)
        at com.ning.http.client.providers.jdk.JDKAsyncHttpProvider$AsyncHttpUrlConnection.call(JDKAsyncHttpProvider.java:227)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

可以看到 com.ning:async-http-client 原本是走 Netty3,拿掉之後改走 HttpURLConnection 才是出現例外的主因。 找到的解法有幾個:

  • 使用 head X-HTTP-Method-Override:測試不可行。
  • 複寫 HttpURLConnection.methods:測試不可行,payload 帶不過去。
  • 尋找已解決的 JDK (待確認)
  • 改用新版 org.asynchttpclient:async-http-client;因為底層用的是 Netty4。
  • 改用其他 http client。

雖然 Jersey 也會發生相同問題,但是修改之後可以正常使用。

webTarget.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
Response response = webTarget.path(url)
      .request(MediaType.APPLICATION_JSON)
      .method("PATCH", Entity.json(payload.toString()));

參考資料:

沒有留言:

張貼留言

[Java] Invalid HTTP method: PATCH

最近系統需要使用 Netty4,所以把衝突的 Netty3 拆掉,然後就出現了例外。 pom.xml <dependency> <groupId>com.ning</groupId> <artifactId>as...