最近系統需要使用 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()));
參考資料: