StackExchange API からの JSON URL がぎこちないものを返しますか?
-
04-10-2019 - |
質問
ここで何か間違ったことをしているような気がしますが、手順が間違っているのか、それとも単にエンコードの問題か何かが発生しているのかはよくわかりません。私のコードは次のとおりです。
URL url = new URL("http://api.stackoverflow.com/0.8/questions/2886661");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
// Question q = new Gson().fromJson(in, Question.class);
String line;
StringBuffer content = new StringBuffer();
while ((line = in.readLine()) != null)
{
content.append(line);
}
コンテンツを印刷すると、大量のウィングディングや特殊文字が表示され、基本的にはぎこちないものになります。ここにコピーして貼り付けますが、うまくいきません。私の何が間違っているのでしょうか?
解決
この場合、それは文字エンコーディングの問題ではなく、コンテンツのエンコーディングの問題です。テキストを期待していますが、サーバーは帯域幅を節約するために圧縮を使用しています。その URL を取得したときにヘッダーを見ると、接続しているサーバーが gzip 圧縮されたコンテンツを返していることがわかります。
GET /0.8/questions/2886661 HTTP/1.1
Host: api.stackoverflow.com
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 22 May 2010 15:51:34 GMT
Content-Type: application/json; charset=utf-8
<more headers>
Content-Encoding: gzip
<more headers>
したがって、stevedbrownが示唆しているように、ApacheのHttpClientのようなよりスマートなクライアントを使用する必要があります(ただし、 Gzip を自動的に読み上げるように調整する)、またはサンプルコードで取得したストリームを明示的に解凍します。代わりに、入力を宣言する行でこれを試してください。
BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(url.openStream())));
取得しようとしている URL でこれが機能することを確認しました。
他のヒント
使用 Apache HTTP クライアント 代わりに、文字変換が適切に処理されます。から そのサイトの例:
public final static void main(String[] args) throws Exception {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget =
new HttpGet("http://api.stackoverflow.com/0.8/questions/2886661");
System.out.println("executing request " + httpget.getURI());
// Create a response handler
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpget, responseHandler);
System.out.println(responseBody);
System.out.println("----------------------------------------");
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
この場合、次を参照してください。 http://svn.apache.org/repos/asf/httpcomponents/httpclient/branches/4.0.x/httpclient/src/examples/org/apache/http/examples/client/ClientGZipContentCompression.java, これは、Gzip コンテンツを処理する方法を示しています。
場合によっては、API 呼び出しの応答が圧縮されることがあります。StackExchange API。ドキュメントに目を通し、使用している圧縮を確認してください。GZIP 圧縮または DEFLATE 圧縮を使用するものもあります。GZIP 圧縮の場合は、以下を使用します。
InputStream is = new URL(url).openStream();
BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(is)));