一、問題
在某個項目中,對接方提供了一個方法,但是GET方式提交Body數據,之前確實聽說過GET方法可以傳body數據(像ES里面好像都是這種操作,但是其他系統還沒怎么碰到過),但是並沒有實操過,因此花了好多的時間去解決。
百度了很久,有一些較為有用的信息,在這邊記錄一下,以免下次再遇到。
項目就是最基礎的Spring Boot框架,沒什么特殊的。
二、處理
1、ApacheHttpClient
項目原本引用的是ApacheHttpClient,但研究了許久,更新到最新的4.5.10,並未發現HttpGet中有setEntity方法(一般postByJson方法將body塞到Entity里即可),感覺可能是並不支持get傳遞body數據,試了很久,最終放棄。
方法一:
后來經過大佬點撥,HttpGet繼承了HttpRequestBase,
而HttpPost繼承了HttpEntityEnclosingRequestBase,
HttpEntityEnclosingRequestBase繼承了HttpRequestBase外又實現了HttpEntityEnclosingRequest了的方法(就是關鍵的與Entity有關的方法),
兩者本質上都是繼承了HttpRequestBase,因此考慮自己寫一個HttpGet替代原生的HttpGet,經過試驗確實有用。
類其實直接copy HttpGet即可,修改一下繼承的類就行。
public class HttpDefineGet extends HttpEntityEnclosingRequestBase { public final static String METHOD_NAME = "GET"; public HttpDefineGet() { super(); } public HttpDefineGet(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpDefineGet(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } }
使用時:
HttpRequestBase request = new HttpDefineGet(url); ((HttpDefineGet) request).setEntity((HttpEntity) param);
方法二:
后來經過另一個大佬點撥,提供了httpClient的另一個get傳遞body使用方法:
public static String getWithBody(String uri, String json) { try (CloseableHttpClient httpClient = HttpClients.createDefault()) { RequestBuilder requestBuilder = RequestBuilder.get(uri); requestBuilder.addHeader("Content-type", "application/json"); StringEntity jsonBody = new StringEntity(json, ContentType.APPLICATION_JSON); requestBuilder.setEntity(jsonBody); HttpUriRequest httpRequest = requestBuilder.build(); try (CloseableHttpResponse httpResponse = httpClient.execute(httpRequest)) { if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { return EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); } else { return ""; } } } catch (IOException e) { // Do some log staff } return ""; }
2、AsyncHttpClient
找了一些資料,說是AsyncHttpClient有get傳遞body的方法,因此還是在項目里導入了AsyncHttpClient的依賴。
<dependency> <groupId>org.asynchttpclient</groupId> <artifactId>async-http-client</artifactId> <version>2.10.4</version> </dependency>
同步請求,因此也沒有特別的處理。
// 構建client AsyncHttpClient client = new DefaultAsyncHttpClient(); // 由於請求傳參是json String jsonBody = "{\"page\":{\"page\":1,\"size\":10}}"; Future<Response> feature = client.prepareGet(url) .setBody(jsonBody) .setHeader("Content-Type","application/json;charset=UTF-8") .execute(); // 發起請求 Response response = feature.get(); // 獲取返回值 String result = response.getResponseBody();
結果在responseBody里面。
