詳解java如何實現(xiàn)帶RequestBody傳Json參數(shù)的GET請求
在調(diào)試Fate平臺時,我遇到了一個奇葩的接口類型。該接口為Get方式,入?yún)⑹且粋€json類型在body中傳遞。我非常費解使用body中傳參的話為什么不用POST請求而使用了GET請求?
在本篇文章中加入了自己對這個問題的一點理解,以及通過java請求這個接口的完整可使用案例。(包括返回string類型和文件流類型)
一、接口調(diào)用方法
當我看到這個接口的時候,我是有點懵的。Get請求為什么要采用這樣的參數(shù)傳遞方式,一般來說GET請求就直接將參數(shù)拼接在URL中了。
二、傳參方式的討論
GET和POST請求和其常見的傳參方式
我們知道GET和POST請求是HTTP協(xié)議中的兩種最常用的請求方式,它們在處理參數(shù)和數(shù)據(jù)傳輸方面差距還是比較大的。
參數(shù)傳遞方式:GET請求的參數(shù)直接附加在URL的末尾,而POST請求的參數(shù)則包含在請求體中。
這意味著GET請求的參數(shù)是明文傳輸?shù)?,因此在請求過程中可能會被記錄或泄露。而POST請求的參數(shù)則是加密的,相對更安全。
參數(shù)的數(shù)據(jù)類型:GET請求的參數(shù)只能發(fā)送簡單的字符串,而POST請求可以發(fā)送復雜的數(shù)據(jù)類型,如表單數(shù)據(jù)、JSON數(shù)據(jù)等。
這使得POST請求相比GET請求在傳遞復雜數(shù)據(jù)時更為方便和靈活。
請求的語義:GET請求通常用于獲取或檢索數(shù)據(jù),而POST請求則用于提交數(shù)據(jù)或執(zhí)行某些操作。
緩存機制:GET請求默認開啟瀏覽器緩存機制,因為它的主要目的是獲取數(shù)據(jù),而POST請求則默認禁用緩存機制,因為它可能對服務器上的資源進行修改。
參數(shù)長度限制:由于GET請求的參數(shù)附加在URL上,因此參數(shù)長度受到URL長度的限制。而POST請求的參數(shù)放在請求體中,理論上沒有長度限制,但實際上服務器和客戶端可能會有最大長度限制。
3、4、5意味著根據(jù)不同的需求,選擇合適的請求方式是很重要的。
其實GET帶使用body中傳參,從請求方面講符合了GET請求的語義(獲取和檢索數(shù)據(jù))有能應用到混存機制。從參數(shù)方面講有能突破長度和數(shù)據(jù)類型的限制,同時參數(shù)傳遞更安全。
GET使用請求體傳參的合理性
對于GET請求通過body傳參的情況可以說非常罕見,很多老java都沒見過,也算是給我開了眼了。
根據(jù)以往的經(jīng)驗,我們約定俗成,GET傳參通過URL拼接,POST傳參通過body傳輸。于是有些HTTP庫(如OkHttp)是不允許GET請求帶有請求體的,默認通過post傳請求體。
雖然官方不推薦這樣做,但是,http(基于tcp的超文本傳輸協(xié)議)并沒有規(guī)定Get請求不能加body。
所以這個請求自有其合理性。
三、java實現(xiàn)GET使用請求體傳參請求的技術選型
在公司封裝好的Http請求方法類中,我們采用的是OkHttp,很不幸的是他不支持GET使用請求體傳參。
于是通過網(wǎng)絡搜索,我們選定了兩個方法。一個是AsyncHttpClient,另一個是apache.http.client。
參考文檔:
httpclient實現(xiàn)HttpGet請求傳body的json參數(shù)的
考慮到我們沒有異步請求方面的需求,于是最后選定了apache.http.client
四、完整實現(xiàn)
1.pom引入關鍵依賴
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.5.6</version> </dependency>
2.定義HttpGet實體類
這個實體類主要供后續(xù)實現(xiàn)的方法類調(diào)用,可以單獨作為一個類,也可以將其作為方法類的子類。
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import java.net.URI; public class HttpGetWithEntity extends HttpEntityEnclosingRequestBase { private final static String METHOD_NAME = "GET"; public HttpGetWithEntity() { super(); } public HttpGetWithEntity(final URI uri) { super(); setURI(uri); } HttpGetWithEntity(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } }
3.實現(xiàn)方法類
這里實現(xiàn)了兩個方法,都是通過GET請求傳遞請求體數(shù)據(jù)的(請求體數(shù)據(jù)已轉換為為JsonString)。
區(qū)別在于一個是正常返回String類型Response。另一個是返回文件流并將文件流寫入到文件中。
import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @Slf4j public class ApacheHttpUitls { public static String getResponseByJson(String url, String param, String encoding) throws Exception { String body = ""; //創(chuàng)建httpclient對象 CloseableHttpClient client = HttpClients.createDefault(); HttpGetWithEntity httpGetWithEntity = new HttpGetWithEntity(url); HttpEntity httpEntity = new StringEntity(param, ContentType.APPLICATION_JSON); httpGetWithEntity.setEntity(httpEntity); //執(zhí)行請求操作,并拿到結果 CloseableHttpResponse response = client.execute(httpGetWithEntity); //獲取結果實體 HttpEntity entity = response.getEntity(); if (entity != null) { //按指定編碼轉換結果實體為String類型 body = EntityUtils.toString(entity, encoding); } //釋放鏈接 response.close(); return body; } public static boolean getStreamGetResponse(String url, String requestBody, String outputFilePath) throws Exception { InputStream inputStream = null; OutputStream outputStream = null; CloseableHttpResponse response = null; try{ //創(chuàng)建httpclient對象 CloseableHttpClient client = HttpClients.createDefault(); HttpGetWithEntity httpGetWithEntity = new HttpGetWithEntity(url); HttpEntity httpEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); httpGetWithEntity.setEntity(httpEntity); //執(zhí)行請求操作,并拿到結果 response = client.execute(httpGetWithEntity); //獲取結果實體 HttpEntity entity = response.getEntity(); log.info("requestUrl: {}, requestBody: {}", url, requestBody); if (entity != null) { inputStream = entity.getContent(); Path path = Paths.get(outputFilePath); if (!Files.exists(path)) { try { Files.createFile(path); } catch (IOException e) { log.error("File create error ", e); // 處理異常,例如輸出錯誤消息或退出程序 } } outputStream = Files.newOutputStream(path); byte[] buffer = new byte[1024]; // 可以根據(jù)需要調(diào)整緩沖區(qū)大小 int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } log.info("File downloaded and saved at " + outputFilePath); }else{ log.error("Http get Entity is null"); return false; } return true; } catch (Exception e){ log.error("File download error ", e); return false; } finally { //釋放鏈接 if (response != null) response.close(); if (inputStream != null) inputStream.close(); if (outputStream != null) outputStream.close(); } } }
以上就是詳解java如何實現(xiàn)帶RequestBody傳Json參數(shù)的GET請求的詳細內(nèi)容,更多關于java帶RequestBody傳Json參數(shù)的資料請關注腳本之家其它相關文章!
相關文章
完美解決java.lang.OutOfMemoryError處理錯誤的問題
下面小編就為大家?guī)硪黄昝澜鉀Qjava.lang.OutOfMemoryError處理錯誤的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01JavaAgent實現(xiàn)http接口發(fā)布方式淺析
這篇文章主要介紹了JavaAgent實現(xiàn)http接口發(fā)布方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-03-03