1. 程式人生 > >HttpClient傳送請求後得到的響應內容出現部分亂碼的問題

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進行的操作,中間不涉及包裝類的額外編碼附操作。