欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

restemplate請求亂碼之content-encoding=“gzip“示例詳解

 更新時間:2024年03月29日 11:18:36   作者:一名技術(shù)極客  
RestTemplate從Spring3.0開始支持的一個HTTP請求工具,它提供了常見的REST請求方案的模板,及一些通用的請求執(zhí)行方法 exchange 以及 execute,接下來通過本文給大家介紹restemplate請求亂碼之content-encoding=“gzip“,需要的朋友可以參考下

什么是 RestTemplate

  RestTemplate 是從 Spring3.0 開始支持的一個 HTTP 請求工具,它提供了常見的 REST請求方案的模板,例如 GET 請求、POST 請求、PUT 請求、DELETE 請求以及一些通用的請求執(zhí)行方法 exchange 以及 execute。RestTemplate 繼承自 InterceptingHttpAccessor 并且實現(xiàn)了 RestOperations 接口,其中 RestOptions 接口定義了基本的 RESTful 操作,這些操作在 RestTemplate 中都得到了實現(xiàn)。

restemplate請求亂碼之content-encoding="gzip"

今天有一個通過Restemplate請求一個天氣API,發(fā)現(xiàn)其Body數(shù)據(jù)是亂碼,同事處理了好久,然并卵,經(jīng)檢查后,發(fā)現(xiàn)頭部信息出了問題。

content-encoding="gzip"
content-type="application/json;charset=UTF-8"

返回值是UTF-8,Restemplate設置的也是UTF-8。在翻看其他博客,發(fā)現(xiàn)問題原因是http存在一個壓縮格式:Gzip。

Gzip是一個壓縮算法,當請求數(shù)據(jù)或返回數(shù)據(jù)體積過大,為減少網(wǎng)絡負載壓力而使用的壓縮算法。通常在服務器端使用,客戶端為獲得原始數(shù)據(jù)需通過Gzip解壓。

響應頭中的gzip

Content-Encoding

是一個實體消息首部,用于對特定媒體類型的數(shù)據(jù)進行壓縮。當這個首部出現(xiàn)的時候,它的值表示消息主體進行了何種方式的內(nèi)容編碼轉(zhuǎn)換。這個消息首部用來告知客戶端應該怎樣解碼才能獲取在 Content-Type 中標示的媒體類型內(nèi)容。

一般建議對數(shù)據(jù)盡可能地進行壓縮,因此才有了這個消息首部的出現(xiàn)。

注:客戶端和服務器都可以使用,表示body中的數(shù)據(jù)采用了什么編碼(壓縮算法)

Accept-Encoding

HTTP 請求頭 Accept-Encoding 會將客戶端能夠理解的內(nèi)容編碼方式——通常是某種壓縮算法——進行通知(給服務端)。通過內(nèi)容協(xié)商的方式,服務端會選擇一個客戶端提議的方式,使用并在響應頭 Content-Encoding 中通知客戶端該選擇。

注:一般是客戶端使用,表示給服務器說明,客戶端支持的壓縮算法列表。服務從中選擇一個對響應體進行壓縮。

/**
     * @Title: getClimateByRequst
     * @Description: ( 通過request 獲取天氣信息)
     * @Author:lijie
     * @since 2021/11/9 14:05
     * @Version:1.1.0
     * @return:   climate:封裝的天氣結(jié)果類
     */
public Result<Climate> getClimateByRequst(HttpServletRequest request) {
    Result<Climate> result=new Result<>();
    try{
        //通過request請求獲得ip地址
        String ip = WebUtils.getIpByRequset(request);
        //通過ip獲得大致定位
        Result<Map<String, Object>> locationByIP = this.getLocationByIP(ip);
        if(locationByIP!=null&&locationByIP.isSuccess()){
            Map<String, Object> data = locationByIP.getData();
            String url=""http://請求的url地址
            if(MapUtils.isNotEmpty(data)){
                String jd = MapUtils.getString(data, "jd");//精度
                String wd = MapUtils.getString(data, "wd");//緯度
                HttpHeaders httpHeaders = new HttpHeaders();
                // Accept 表示客戶端支持什么格式的響應體
                httpHeaders.set("contentType", "application/json;charset=UTF-8");
                // Accept-Encoding 頭,表示客戶端可以接收gzip格式的壓縮
                httpHeaders.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
                //發(fā)送請求 
                ResponseEntity<byte[]> forEntity = restTemplate.exchange
                        (url, HttpMethod.GET, new HttpEntity<>(httpHeaders), byte[].class);
                if(forEntity.getStatusCode()== HttpStatus.OK){
                    // 獲取服務器響應體編碼
                    String contentEncoding = forEntity.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
                    if ("gzip".equals(contentEncoding)) { // 是gzip編碼
                        // gzip解壓服務器的Body響應體
                        byte[] weatherData = WebUtils.unGZip(
                                new ByteArrayInputStream(Objects.requireNonNull(forEntity.getBody())));
                        String weatherJson = new String(weatherData, StandardCharsets.UTF_8);
                        Climate climate = JSONObject.parseObject(weatherJson, Climate.class);
                        if(climate!=null){
                            result.setSuccess();
                            result.setData(climate);
                        }
                    } else {
                        // todo 其他的編碼
                        result.setErrored("和風API響應值編碼不是Gzip,請聯(lián)系我,謝謝");
                    }
                }else{
                    result.setErrored("和風API響應出錯了");
                }
            }
        }
    }catch (Exception e){
        result.setErrored("天氣獲取出錯了");
    }
    return result;
}
/**
	 * Gzip解壓縮
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public static byte[] unGZip(InputStream inputStream) throws IOException {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try (GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream)) {
			byte[] buf = new byte[4096];
			int len = -1;
			while ((len = gzipInputStream.read(buf, 0, buf.length)) != -1) {
				byteArrayOutputStream.write(buf, 0, len);
			}
			return byteArrayOutputStream.toByteArray();
		} finally {
			byteArrayOutputStream.close();
		}
	}
/**
	 * Gzip壓縮數(shù)據(jù)
	 * @param data
	 * @return
	 * @throws IOException
	 */
	public static byte[] gZip(byte[] data) throws IOException {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
			gzipOutputStream.write(data);
			gzipOutputStream.finish();
			return byteArrayOutputStream.toByteArray();
		}
	}

SpringBoot的響應體壓縮配置

實際上,并不需要自己手動去寫這種響應體的壓縮代碼。springboot提供了相關(guān)的配置。只針對響應壓縮

server:
  compression:
    # 開啟響應壓縮
    enabled: true
  # 支持的壓縮類型
  mime-types: 
    - application/json
    - application/xml
    - application/javascript
    - text/html
    - text/xml
    - text/plain
    - text/css
    - text/javascript
  # 默認只有響應體大于 2028kb 時才會進行壓縮
  min-response-size: 2048
  # 指定不壓縮的user-agent,默認為null
  # excluded-user-agents

對應的配置類:org.springframework.boot.context.embedded.Compression

最后

使用RestTemplate請求文本數(shù)據(jù)接口,發(fā)現(xiàn)解碼后的字符串是亂碼。此時除了編碼格式問題外就可以懷疑是不是服務器響應了壓縮后的數(shù)據(jù)。解決這個問題,先嘗試移除Accept-Encoding請求頭,告訴服務器,客戶端不需要壓縮響應體。如果服務器還是響應壓縮后的數(shù)據(jù),嘗試讀取服務器的Content-Encoding頭,根據(jù)服務器的壓縮編碼,自己再進行解壓縮。

到此這篇關(guān)于restemplate請求亂碼之content-encoding=“gzip“的文章就介紹到這了,更多相關(guān)restemplate請求亂碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot整合Javamail實現(xiàn)郵件發(fā)送功能

    SpringBoot整合Javamail實現(xiàn)郵件發(fā)送功能

    郵件發(fā)送是一個很普遍的功能,springboot整合了相關(guān)的starter,本文給大家介紹了可以實現(xiàn)一個簡單的郵件發(fā)送功能的實例,文中通過代碼給大家介紹的非常詳細,感興趣的朋友可以參考下
    2023-12-12
  • SpringBoot系列教程JPA之基礎環(huán)境搭建的方法

    SpringBoot系列教程JPA之基礎環(huán)境搭建的方法

    這篇文章主要介紹了SpringBoot系列教程JPA之基礎環(huán)境搭建的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-06-06
  • Feign+mybatisplus搭建項目遇到的坑及解決

    Feign+mybatisplus搭建項目遇到的坑及解決

    這篇文章主要介紹了Feign+mybatisplus搭建項目遇到的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • JAVA 根據(jù)設置的概率生成隨機數(shù)的方法

    JAVA 根據(jù)設置的概率生成隨機數(shù)的方法

    本篇文章主要介紹了JAVA 根據(jù)設置的概率生成隨機數(shù)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • spring啟動錯誤Singleton bean creation not allowed while the singletons of this factory are indestruction

    spring啟動錯誤Singleton bean creation not al

    本文主要介紹了spring啟動錯誤Singleton bean creation not allowed while the singletons of this factory are indestruction,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Java中Integer128的坑

    Java中Integer128的坑

    本文主要介紹了Java中Integer128的坑,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-03-03
  • 在JAR文件中找不到主清單屬性的原因與解決方案

    在JAR文件中找不到主清單屬性的原因與解決方案

    在Java中,一個JAR文件通常包含一個名為MANIFEST.MF的清單文件,這個文件定義了關(guān)于JAR文件的各種元數(shù)據(jù),然而,有時我們可能會遇到一個問題,那就是在JAR文件中找不到主清單屬性,本文給大家介紹了JAR文件中找不到主清單屬性的原因和解決方案,需要的朋友可以參考下
    2024-04-04
  • springboot集成opencv實現(xiàn)人臉識別功能的詳細步驟

    springboot集成opencv實現(xiàn)人臉識別功能的詳細步驟

    大家都知道OpenCV是一個基于BSD許可(開源)發(fā)行的跨平臺計算機視覺和機器學習軟件庫,可以運行在Linux、Windows、Android和Mac OS操作系統(tǒng)上今天通過本文給大家分享springboot集成opencv實現(xiàn)人臉識別,感興趣的朋友一起看看吧
    2021-06-06
  • Eclipse開發(fā)JavaWeb項目配置Tomcat的方法步驟

    Eclipse開發(fā)JavaWeb項目配置Tomcat的方法步驟

    本文主要介紹了Eclipse開發(fā)JavaWeb項目配置Tomcat的方法步驟,首先介紹eclipse開發(fā)JavaWeb項目需要配置的相關(guān)環(huán)境,使用tomcat軟件在本地搭建服務器,然后再在eclipse環(huán)境下配置tomcat,感興趣的可以了解一下
    2021-08-08
  • SpringCloud集成AlloyDB的示例代碼

    SpringCloud集成AlloyDB的示例代碼

    AlloyDB?是?Google?Cloud?提供的一種高度可擴展、強性能的關(guān)系型數(shù)據(jù)庫服務,它兼容?PostgreSQL,并提供了更快的查詢性能和更高的可用性,本文給大家介紹了如何使用SpringCloud集成AlloyDB,需要的朋友可以參考下
    2025-01-01

最新評論