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

Posted 小熊vip

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpClient发送请求后得到的响应内容出现部分乱码的问题相关的知识,希望对你有一定的参考价值。

这几天爬虫出现了一个问题,用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进行的操作,中间不涉及包装类的额外编码附操作。

以上是关于HttpClient发送请求后得到的响应内容出现部分乱码的问题的主要内容,如果未能解决你的问题,请参考以下文章

MVC HttpClient多个post请求,得到不匹配的响应

使用httpclient发送post请求与get请求

http请求和Http响应包含哪些内容

如何从 POST 请求中检索 cookie?

HTTP协议入门

使用“application/x-www-form-urlencoded”内容类型请求标头时,未正确发送 HttpClient 后正文参数