web-dev-qa-db-ja.com

HttpURLConnectionから完全な応答を読み取る方法

私はandoridでHTTPヘッダーを変更するプロキシサーバーを作成しますが、正常に動作しますが、「トップレイヤー」に完全な応答を転送する必要があります。
HttpURLConnectionからの応答全体(すべてのヘッダー、コンテンツ、すべて)を読み取るにはどうすればよいですか?

HttpURLConnection httpURLConnection;
URL url = new URL(ADDRESS);
httpURLConnection = (HttpURLConnection) url.openConnection();
// add headers, write output stream, flush
if (httpURLConnection.getResponseCode() == HttpsURLConnection.HTTP_OK)
{
    Map<String, List<String>> map = httpURLConnection.getHeaderFields();
    System.out.println("Printing Response Header...\n");

    for (Map.Entry<String, List<String>> entry : map.entrySet())
    {
        System.out.println("Key : " + entry.getKey() + " ,Value : " + entry.getValue());
    }

    return new DataInputStream(httpURLConnection.getInputStream());
}

GetInputStreamでコンテンツのみを受信した場合、reposneを含むストリームを作成できますか?

18
Andrzej

HttpURLConnectionを使用して完全なHTTP応答を直接ダンプする方法はありませんが、さまざまな方法を使用して再構築できます。例えば、

HttpURLConnection httpURLConnection;
URL url = new URL("http://www.google.com");
httpURLConnection = (HttpURLConnection) url.openConnection();
StringBuilder builder = new StringBuilder();
builder.append(httpURLConnection.getResponseCode())
       .append(" ")
       .append(httpURLConnection.getResponseMessage())
       .append("\n");

Map<String, List<String>> map = httpURLConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet())
{
    if (entry.getKey() == null) 
        continue;
    builder.append( entry.getKey())
           .append(": ");

    List<String> headerValues = entry.getValue();
    Iterator<String> it = headerValues.iterator();
    if (it.hasNext()) {
        builder.append(it.next());

        while (it.hasNext()) {
            builder.append(", ")
                   .append(it.next());
        }
    }

    builder.append("\n");
}

System.out.println(builder);

プリント

200 OK
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Date: Tue, 07 Jan 2014 16:06:45 GMT
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
X-XSS-Protection: 1; mode=block
Expires: -1
Alternate-Protocol: 80:quic
Set-Cookie: NID=67=OIu8_xhcxE-UPCSfIoTINvRyOe4ALVhIqan2NUI6LMdRkSJHTPGvNkYeYE--WqPSEPK4c4ubvmjWGUyFgXsa453KHavX9gUeKdzfInU2Q25yWP3YtMhsIhJpUQbYL4gq; expires=Wed, 09-Jul-2014 16:06:45 GMT; path=/; domain=.google.ca; HttpOnly, PREF=ID=4496ed99b812997d:FF=0:TM=1389110805:LM=1389110805:S=jxodjb3UjGJSZGaF; expires=Thu, 07-Jan-2016 16:06:45 GMT; path=/; domain=.google.ca
Content-Type: text/html; charset=ISO-8859-1
Server: gws
Cache-Control: private, max-age=0

その後、InputStreamを取得して、そのコンテンツも印刷できます。

29

似たような問題を探したとき、最初は私には明らかではなかったので、解決策を見つけました。

ボディレスポンスを読む:

readFullyAsString(connection.getInputStream(), "UTF-8");

そして、これは https://stackoverflow.com/a/10505933/128135 から来ています。

public String readFullyAsString(InputStream inputStream, String encoding) throws IOException {
        return readFully(inputStream).toString(encoding);
    }

    private ByteArrayOutputStream readFully(InputStream inputStream) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = 0;
        while ((length = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, length);
        }
        return baos;
    }
3
Greg