سؤال

لدي شعور بأنني أفعل شيئًا خاطئًا هنا ، لكنني لست متأكدًا تمامًا مما إذا كنت أفتقد خطوة ، أو أواجه مشكلة تشفير أو شيء ما. هذا هو الكود الخاص بي:

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);
   }

عندما أقوم بطباعة المحتوى ، أحصل على مجموعة كاملة من الأجنحة والشخصيات الخاصة ، في الأساس Jibberish. أود أن أسسها وتجاوزها هنا ، لكن هذا لا يعمل. ما الخطأ الذي افعله؟

هل كانت مفيدة؟

المحلول

في هذه الحالة ، إنها ليست مشكلة في تشفير الأحرف ، إنها مشكلة في ترميز المحتوى ؛ أنت تتوقع نصًا ، لكن الخادم يستخدم الضغط لحفظ النطاق الترددي. إذا نظرت إلى الرؤوس عند الاستيلاء على عنوان URL هذا ، يمكنك رؤية الخادم الذي تتصل به هو إرجاع محتوى Gzipped:

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>

لذلك تحتاج إما إلى استخدام عميل أكثر ذكاءً مثل httpclient من Apache كما يوحي StevedBrown (على الرغم من أنك بحاجة قرص لجعله يتحدث 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/clientgzipcontentctompression.java, ، والذي يوضح كيفية التعامل مع محتوى GZIP.

في بعض الأحيان يتم ضغط استجابة استدعاء API على سبيل المثال. Stacexchange API. يرجى الاطلاع على وثائقهم والتحقق من الضغط الذي يستخدمونه. يستخدم البعض إما GZIP أو انتشار الضغط. في حالة ضغط GZIP استخدم ما يلي.

InputStream is = new URL(url).openStream();
BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(is)));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top