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

restemplate請(qǐng)求亂碼之content-encoding=“gzip“示例詳解

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

什么是 RestTemplate

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

restemplate請(qǐng)求亂碼之content-encoding="gzip"

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

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

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

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

響應(yīng)頭中的gzip

Content-Encoding

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

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

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

Accept-Encoding

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

注:一般是客戶端使用,表示給服務(wù)器說(shuō)明,客戶端支持的壓縮算法列表。服務(wù)從中選擇一個(gè)對(duì)響應(yīng)體進(jìn)行壓縮。

/**
     * @Title: getClimateByRequst
     * @Description: ( 通過(guò)request 獲取天氣信息)
     * @Author:lijie
     * @since 2021/11/9 14:05
     * @Version:1.1.0
     * @return:   climate:封裝的天氣結(jié)果類(lèi)
     */
public Result<Climate> getClimateByRequst(HttpServletRequest request) {
    Result<Climate> result=new Result<>();
    try{
        //通過(guò)request請(qǐng)求獲得ip地址
        String ip = WebUtils.getIpByRequset(request);
        //通過(guò)ip獲得大致定位
        Result<Map<String, Object>> locationByIP = this.getLocationByIP(ip);
        if(locationByIP!=null&&locationByIP.isSuccess()){
            Map<String, Object> data = locationByIP.getData();
            String url=""http://請(qǐng)求的url地址
            if(MapUtils.isNotEmpty(data)){
                String jd = MapUtils.getString(data, "jd");//精度
                String wd = MapUtils.getString(data, "wd");//緯度
                HttpHeaders httpHeaders = new HttpHeaders();
                // Accept 表示客戶端支持什么格式的響應(yīng)體
                httpHeaders.set("contentType", "application/json;charset=UTF-8");
                // Accept-Encoding 頭,表示客戶端可以接收gzip格式的壓縮
                httpHeaders.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
                //發(fā)送請(qǐng)求 
                ResponseEntity<byte[]> forEntity = restTemplate.exchange
                        (url, HttpMethod.GET, new HttpEntity<>(httpHeaders), byte[].class);
                if(forEntity.getStatusCode()== HttpStatus.OK){
                    // 獲取服務(wù)器響應(yīng)體編碼
                    String contentEncoding = forEntity.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
                    if ("gzip".equals(contentEncoding)) { // 是gzip編碼
                        // gzip解壓服務(wù)器的Body響應(yīng)體
                        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("和風(fēng)API響應(yīng)值編碼不是Gzip,請(qǐng)聯(lián)系我,謝謝");
                    }
                }else{
                    result.setErrored("和風(fēng)API響應(yīng)出錯(cuò)了");
                }
            }
        }
    }catch (Exception e){
        result.setErrored("天氣獲取出錯(cuò)了");
    }
    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的響應(yīng)體壓縮配置

實(shí)際上,并不需要自己手動(dòng)去寫(xiě)這種響應(yīng)體的壓縮代碼。springboot提供了相關(guān)的配置。只針對(duì)響應(yīng)壓縮

server:
  compression:
    # 開(kāi)啟響應(yīng)壓縮
    enabled: true
  # 支持的壓縮類(lèi)型
  mime-types: 
    - application/json
    - application/xml
    - application/javascript
    - text/html
    - text/xml
    - text/plain
    - text/css
    - text/javascript
  # 默認(rèn)只有響應(yīng)體大于 2028kb 時(shí)才會(huì)進(jìn)行壓縮
  min-response-size: 2048
  # 指定不壓縮的user-agent,默認(rèn)為null
  # excluded-user-agents

對(duì)應(yīng)的配置類(lèi):org.springframework.boot.context.embedded.Compression

最后

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

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

相關(guān)文章

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

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

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

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

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

    Feign+mybatisplus搭建項(xiàng)目遇到的坑及解決

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

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

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

    spring啟動(dòng)錯(cuò)誤Singleton bean creation not al

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

    Java中Integer128的坑

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

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

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

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

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

    Eclipse開(kāi)發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟

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

    SpringCloud集成AlloyDB的示例代碼

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

最新評(píng)論