我有一种感觉,我在这里做错了,但我不太确定我是否错过了一步,或者只是遇到了编码问题。这是我的代码:
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);
}
当我打印内容时,我得到了一大堆翼形和特殊字符,基本上是乱七八糟。我会复制并通过它,但这不起作用。我做错了什么?
答案 0 :(得分:5)
在这种情况下,它不是字符编码问题,而是内容编码问题;你期待文本,但服务器正在使用压缩来节省带宽。如果您在获取该网址时查看标题,则可以看到您要连接的服务器正在返回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>
因此,您需要使用像Apache的HttpClient这样的更智能的客户端,因为stevedbrown建议(尽管您需要a tweak to get it to speak Gzip automatically),或者明确解压缩您在示例代码中获得的流。请尝试使用此代替您声明输入的行:
BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(url.openStream())));
我已经确认这适用于你想要抓住的网址。
答案 1 :(得分:1)
使用Apache Http Client代替,它将正确处理字符转换。来自that site's examples:
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内容。
答案 2 :(得分:1)
有时API调用响应会被压缩,例如。 StackExchange API。请查看他们的文档并检查他们使用的压缩程序。有些使用GZIP或DEFLATE压缩。如果是GZIP压缩,请使用以下内容。
InputStream is = new URL(url).openStream();
BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(is)));