URL JSON из API StackExchange возвращает нелицензионное письмо?

У меня такое ощущение, что я что-то здесь не так делаю, но я не совсем уверен, пропустил ли я шаг, или у меня просто проблема с кодировкой или что-то в этом роде. Вот мой код:

URL url = new URL("http://api.stackru.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);
   }

Когда я печатаю контент, я получаю целую кучу крылышек и специальных символов, в основном фальшивку. Я бы скопировал и пропустил это здесь, но это не работает. Что я делаю неправильно?

3 ответа

Решение

В этом случае это не проблема кодировки символов, это проблема кодирования контента; вы ожидаете текст, но сервер использует сжатие для экономии пропускной способности. Если вы посмотрите на заголовки, когда получаете этот URL-адрес, вы увидите, что сервер, к которому вы подключаетесь, возвращает сжатый контент:

GET /0.8/questions/2886661 HTTP/1.1
Host: api.stackru.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>

Так что вам нужно либо использовать более умного клиента, такого как HttpClient от Apache, как предполагает stevedbrown (хотя вам нужен твик, чтобы он автоматически говорил на Gzip), либо явно распаковать поток, полученный в вашем примере кода. Попробуйте это вместо строки, где вы объявляете свой ввод:

 BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(url.openStream())));

Я убедился, что это работает для URL, который вы пытаетесь получить.

Иногда ответ на вызов API сжимается, например. StackExchange API. Пожалуйста, просмотрите их документацию и проверьте, какое сжатие они используют. Некоторые используют сжатие GZIP или DEFLATE. В случае сжатия GZIP используйте следующее.

InputStream is = new URL(url).openStream();
BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(is)));

Используйте вместо этого Apache Http Client, он позаботится о преобразовании символов должным образом. Из примеров этого сайта:

public final static void main(String[] args) throws Exception {

    HttpClient httpclient = new DefaultHttpClient();

    HttpGet httpget = 
        new HttpGet("http://api.stackru.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-контентом.

Другие вопросы по тегам