今天请求一个天气接口,发现一直乱码,开始没注意看请求头信息,平时 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 、请求都乱码。如下图。
360 Chrome,和模式下都不乱码。
我们通过查询编码,为 UTF-8,但是我 HTTP 设置请求编码为UTF-8,照样乱码。
这次请求乱码好像把我难住了,我开始怀疑这个接口是不是有来源判断,故意乱码的,后来发现应该不会,理由很简单,因为这个接口是一个支持 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 包下载,见附件。
总结,一定要看请求头信息。
附件下载:
备注:点击文件名下载,附件源来自云端,只能在本站下载。复制下载链接无效。
如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。
¥我需要走的更远,点击我 赞助。
如果还有疑问,点击我加群,为你提供最好的解答。