java http请求 乱码问题_Java 之 HTTP请求乱码解决,GZIP 返回值乱码解决

今天请求一个天气接口,发现一直乱码,开始没注意看请求头信息,平时  HTTP  请求无非几种方法解决乱码问题。其实只要注意一点就可以了,编码一致即可,其次对方怎么编码,接收方怎么解码即可。

HTTP请求乱码解决方案一

这也是最简单的方式,主要是用IOUtils工具类。URL realUrl = new URL(url);

// 打开和URL之间的连接

conn = (HttpURLConnection) realUrl.openConnection();

// 发送POST请求必须设置如下两行

conn.setRequestMethod(StringUtils.upperCase(type));// 提交模式

conn.setDoInput(true);

conn.setDoOutput(true);

conn.setUseCaches(false);

conn.setRequestProperty("Connection", "close");

conn.setConnectTimeout(3000); //设置连接主机超时(单位:毫秒)

conn.setReadTimeout(2000); //设置从主机读取数据超时(单位:毫秒)

//省略一些代码

//获取InputStream

InputStream inStream = conn.getInputStream();

//通过IOUtils 转化,把流转换为字符串。

//charset为编码格式,可选为"utf-8","gbk","gb2312"等等

String result = IOUtils.toString(inStream,charset);

HTTP请求乱码解决方案二

接着上面的代码,用我们最常用的方式,一行一行的读,charset同上面一样。StringBuffer sb = new StringBuffer("");

in = new BufferedReader(new InputStreamReader(inStream, charset));

String line = "";

while ((line = in.readLine()) != null){

sb.append(line);

}

result = sb.toString();

我遇到的HTTP乱码异常

我遇到的乱码情况如下,  JSONP  请求不乱码,浏览器  Chrome  、  Firefox  、请求都乱码。如下图。

e76abbb3826f2ee8465ae74c7dc3a942.png

aad2ac4a0d6b37deeb40439cb88ec83b.png

360 Chrome,和模式下都不乱码。

3fe6f58dce21a55d8a3778d9a642ad9d.png

我们通过查询编码,为 UTF-8,但是我  HTTP  设置请求编码为UTF-8,照样乱码。

0ac1e1c9223ff866f0e7c87ddec6de24.png

这次请求乱码好像把我难住了,我开始怀疑这个接口是不是有来源判断,故意乱码的,后来发现应该不会,理由很简单,因为这个接口是一个支持  JSONP  的接口,而且现在有网站正在使用。

经过各种转码后,都没有结果,一直乱码。发现忽略了一个问题。

经过仔细查看,发现返回的内容为Content-Encoding : gzip,所以我们经常看到这种返回值就不要把编码再转来转去了。。[0x0][0x0][0x0][0x0][0x0][0x0]

[0xad][0x93][0xdf]J[0x2]A[0x14][0xc6]_%[0xe6]z[0x3]][0xd7][0xfc][0xf3][\n]

[0xf4][0x0][0xd1][0xc5][0xa0][0xeb]*[0x98][0x96][0xbb][0xa2]"[0xb][0xa2][0x92]

[0xa8]Ra[0x83][0x7][0x95][0xb4]o[0xa1]H[0xa6]sp[0x6][0x10]ux[0xfd][0x1f][0xe]HG[0x1d]

处理方式用java.util.zip下的工具类来先解压解决,接着上面的代码。InputStream stream = new GZIPInputStream(conn.getInputStream());

BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"utf-8"));

StringBuffer sb = new StringBuffer();

String line = "";

while ((line = reader.readLine()) != null){

sb.append(line);

}

System.out.println(sb.toString());

或者如下:InputStream stream = new GZIPInputStream(conn.getInputStream());

String str = IOUtils.toString(stream,"utf-8");

整个代码:URL realUrl = new URL("https://www.sojson.com/");

// 打开和URL之间的连接

HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();

// 发送POST请求必须设置如下两行

conn.setRequestMethod("GET");// 提交模式

conn.setDoInput(true);

conn.setDoOutput(false);

conn.setUseCaches(false);

conn.setRequestProperty("Connection", "close");

conn.setConnectTimeout(3000); //设置连接主机超时(单位:毫秒)

conn.setReadTimeout(2000); //设置从主机读取数据超时(单位:毫秒)

InputStream stream = new GZIPInputStream(conn.getInputStream());

String str = IOUtils.toString(stream,"utf-8");

OK,解决了。采用 JSON在线解析 输出结果如下:{

"desc": "OK",

"status": 1000,

"data": {

"wendu": "21",

"ganmao": "各项气象条件适宜,无明显降温过程,发生感冒机率较低。",

"forecast": [

{

"fengxiang": "南风",

"fengli": "微风级",

"high": "高温 28℃",

"type": "晴",

"low": "低温 15℃",

"date": "15日星期一"

},

{

"fengxiang": "南风",

"fengli": "3-4级",

"high": "高温 32℃",

"type": "多云",

"low": "低温 17℃",

"date": "16日星期二"

},

{

"fengxiang": "南风",

"fengli": "微风级",

"high": "高温 34℃",

"type": "晴",

"low": "低温 19℃",

"date": "17日星期三"

},

{

"fengxiang": "南风",

"fengli": "微风级",

"high": "高温 35℃",

"type": "晴",

"low": "低温 23℃",

"date": "18日星期四"

},

{

"fengxiang": "南风",

"fengli": "微风级",

"high": "高温 34℃",

"type": "多云",

"low": "低温 22℃",

"date": "19日星期五"

}

],

"yesterday": {

"fl": "3-4级",

"fx": "东北风",

"high": "高温 27℃",

"type": "多云",

"low": "低温 14℃",

"date": "14日星期日"

},

"aqi": "81",

"city": "北京"

}

}

哦,上面的org.apache.commons.io.IOUtils 的   Maven  方式:

commons-io

commons-io

2.4

org.apache.commons.io.IOUtils Jar 包下载,见附件。

总结,一定要看请求头信息。

附件下载:

备注:点击文件名下载,附件源来自云端,只能在本站下载。复制下载链接无效。

如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。

¥我需要走的更远,点击我 赞助。

如果还有疑问,点击我加群,为你提供最好的解答。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值