您的位置:首页 > 理论基础 > 计算机网络

HttpClient发送请求后得到的响应内容出现部分乱码的问题

2015-10-26 23:13 609 查看
这几天爬虫出现了一个问题,用HttpClient不管是发送的Post请求还是Get请求一直出现一个问题:得到的响应内容部分乱码,请注意我的措辞,是部分乱码,一小部分,一小部分,一小部分!!!

出问题的代码在这里:

package com.springapp.parse;

import org.apache.http.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
* Created by BearSmall on 2015/10/26.
* 响应工具类
*/
public class ResponseUtils {
/**
* 返回响应正文(有乱码)
* @param response
* @return
*/
public static String getResponseString(HttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();//响应实体类
StringBuilder result = new StringBuilder();//响应正文
if (entity != null) {
String charset = getContentCharSet(entity);
InputStream instream = entity.getContent();

BufferedReader br = new BufferedReader(new InputStreamReader(
instream));
String temp = "";
while ((temp = br.readLine()) != null) {
String str = new String(temp.getBytes(), "UTF-8");
result.append(str+"\n");
}
}
return result.toString();
}
}


发现这段代码出现了乱码问题,已知的情况是:响应的正文是utf-8格式的。出问题的地方也是这个位子。由于对java编码解码理解得不是太透彻,试过很多笨办法,果然解决了部分乱码问题,但是来了个全部乱码。。。。。。。果然是个冷笑话。本来打算就这样了,反正影响不是特别大,但是越往后面这个问题越来越明显。基本上爬下来的大一点的页面都会零零散散的出现乱码现象,很是讨人嫌。

最后发现了问题的症结所在,这里跟大家分享一下:

从代码上看,没有逻辑上的错误。我们就看看细节吧。

首先从响应对象response中得到InputStream 流。然后包装成BufferredReader对象。最后一行一行的读取。但是这样读取的字符串会出现乱码,于是我们从新对读到的每一行字符串重新编码,设置成和inputstream匹配的utf-8。大面积乱码确实不见了,但是却出现小面积的乱码。。。。。。

我们再仔细想一想,我们已经知道inputStream的编码格式为utf-8,那为什么要在最后字符串都一行行读取出来了的情况下将其转化呢?难道不能用另外的方式实现处理这个utf-8,让读出来的一行行的字符串就不存在乱码,这样就省得我们一行行的去重新编码。

果然,看过InputStreamReader的构造函数后,我们发现它有一个两个参数的构造函数,另一个参数就是用来指定字符集的。于是我们果断用上。

package com.springapp.parse;

import org.apache.http.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
* Created by BearSmall on 2015/10/26.
* 响应工具类
*/
public class ResponseUtils {
/**
* 返回响应正文(无乱码)
* @param response
* @return
*/
public static String getResponseString(HttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();//响应实体类
StringBuilder result = new StringBuilder();//响应正文
if (entity != null) {
String charset = getContentCharSet(entity);
InputStream instream = entity.getContent();

BufferedReader br = new BufferedReader(new InputStreamReader(
instream,"utf-8"));
String temp = "";
while ((temp = br.readLine()) != null) {
result.append(temp+"\n");
}
}
return result.toString();
}
}


另外还有其他的做法:

package com.springapp.parse;

import org.apache.http.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
* Created by BearSmall on 2015/10/26.
* 响应工具类
*/
public class ResponseUtils {
/**
* 返回响应正文(无乱码)
* @param response
* @return
*/
public static String getResponseString(HttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();//响应实体类
StringBuilder result = new StringBuilder();//响应正文
if (entity != null) {
InputStream instream = entity.getContent();
byte[] bytes = new byte[4096];
int size = 0;
try {
while ((size = instream.read(bytes)) > 0) {
String str = new String(bytes, 0, size, "utf-8");
result.append(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result.toString();
}


这里由于没有使用包装类,所以需要自己编码解码。但是这里和第一个那种出现乱码的方式还是有区别的,虽然都是自己编码解码,但是这里是对纯的inputStream进行的操作,中间不涉及包装类的额外编码附操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: