restemplate请求乱码之content-encoding=“gzip“

2024-03-28 13:04

本文主要是介绍restemplate请求乱码之content-encoding=“gzip“,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

restemplate请求乱码之content-encoding="gzip"

  • 响应头中的gzip
    • Content-Encoding
    • Accept-Encoding
  • SpringBoot的响应体压缩配置
  • 最后

今天有一个通过Restemplate请求一个天气API,发现其Body数据是乱码,同事处理了好久,然并卵,经检查后,发现头部信息出了问题。

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

返回值是UTF-8,Restemplate设置的也是UTF-8。在翻看其他博客,发现问题原因是http存在一个压缩格式:Gzip。

Gzip是一个压缩算法,当请求数据或返回数据体积过大,为减少网络负载压力而使用的压缩算法。通常在服务器端使用,客户端为获得原始数据需通过Gzip解压。

响应头中的gzip

Content-Encoding

是一个实体消息首部,用于对特定媒体类型的数据进行压缩。当这个首部出现的时候,它的值表示消息主体进行了何种方式的内容编码转换。这个消息首部用来告知客户端应该怎样解码才能获取在 Content-Type 中标示的媒体类型内容。

一般建议对数据尽可能地进行压缩,因此才有了这个消息首部的出现。

注:客户端和服务器都可以使用,表示body中的数据采用了什么编码(压缩算法)

Accept-Encoding

HTTP 请求头 Accept-Encoding 会将客户端能够理解的内容编码方式——通常是某种压缩算法——进行通知(给服务端)。通过内容协商的方式,服务端会选择一个客户端提议的方式,使用并在响应头 Content-Encoding 中通知客户端该选择。

注:一般是客户端使用,表示给服务器说明,客户端支持的压缩算法列表。服务从中选择一个对响应体进行压缩。

在这里插入图片描述

/*** @Title: getClimateByRequst* @Description: ( 通过request 获取天气信息)* @Author:lijie* @since 2021/11/9 14:05* @Version:1.1.0* @return:   climate:封装的天气结果类*/
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=""//请求的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");//发送请求 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,请联系我,谢谢");}}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压缩数据* @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提供了相关的配置。只针对响应压缩

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请求文本数据接口,发现解码后的字符串是乱码。此时除了编码格式问题外就可以怀疑是不是服务器响应了压缩后的数据。解决这个问题,先尝试移除Accept-Encoding请求头,告诉服务器,客户端不需要压缩响应体。如果服务器还是响应压缩后的数据,尝试读取服务器的Content-Encoding头,根据服务器的压缩编码,自己再进行解压缩。

这篇关于restemplate请求乱码之content-encoding=“gzip“的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855694

相关文章

SpringBoot中Get请求和POST请求接收参数示例详解

《SpringBoot中Get请求和POST请求接收参数示例详解》文章详细介绍了SpringBoot中Get请求和POST请求的参数接收方式,包括方法形参接收参数、实体类接收参数、HttpServle... 目录1、Get请求1.1 方法形参接收参数 这种方式一般适用参数比较少的情况,并且前后端参数名称必须

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Java http请求示例

使用HttpURLConnection public static String httpGet(String host) {HttpURLConnection connection = null;try {URL url = new URL(host);connection = (HttpURLConnection) url.openConnection();connection.setReq

10 Source-Get-Post-JsonP 网络请求

划重点 使用vue-resource.js库 进行网络请求操作POST : this.$http.post ( … )GET : this.$http.get ( … ) 小鸡炖蘑菇 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-w

word转PDF后mathtype公式乱码以及图片分辨率降低等一系列问题|完美解决

word转PDF后mathtype公式乱码以及图片分辨率降低等一系列问题|完美解决 问题描述 最近在投一篇期刊论文,直接提交word文档,当时没有查看提交预览,一审审稿意见全是:公式乱码、公式乱码、乱码啊!!!是我大意了,第二次提交,我就决定将word文档转成PDF后再提交,避免再次出现公式乱码的问题。接着问题又来了,我利用‘文件/导出’或‘文件/另存为’的方式将word转成PDF后,发现公式

彻底解决win10系统Tomcat10控制台输出中文乱码

彻底解决Tomcat10控制台输出中文乱码 首先乱码问题的原因通俗的讲就是读的编码格式和写的解码格式不一致,比如最常见的两种中文编码UTF-8和GBK,UTF-8一个汉字占三个字节,GBK一个汉字占两个字节,所以当编码与解码格式不一致时,输出端当然无法识别这是啥,所以只能以乱码代替。 值得一提的是GBK不是国家标准编码,常用的国标有两,一个是GB2312,一个是GB18030 GB1

matplotlib中文乱码问题

在使用Matplotlib进行数据可视化的过程中,经常会遇到中文乱码的问题。显示乱码是由于编码问题导致的,而matplotlib 默认使用ASCII 编码,但是当使用pyplot时,是支持unicode编码的,只是默认字体是英文字体,导致中文无法正常显示,所以显示中文乱码。 文本使用系统默认字体、手动指定字体、使用字体管理器来解决。 一、系统默认字体(全局设置字体) 在Matplotlib中

产出文件乱码问题

产出到文件的部分繁体字字符串出现乱码 主要原因是从数据库读取的字符是GBK,产出的字符串编码设置成立GB2312,字符集部分不匹配,产出字符串的编码改成GBK后问题解决。

项目一(一) HttpClient中的POST请求和GET请求

HttpClient中的POST请求和GET请求 一、HttpClient简述 HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLU