2016-05-31 106 views
0

我想連接我的android應用程序shutterstock api,以便它可以搜索一些圖像那裏。它使用https scheme + Basic Authentication標頭來允許用戶進行所有搜索請求。我在使用HttpsURLConnection的常規Java項目中實現了功能,並能夠獲得正確的JSON響應。 Java代碼看起來是這樣的:Android應用程序連接到shutterstock api拋出IOException異常401

HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();//proxy); 
     String username = "62c01aa824222683004b", password = "dc4ad748a75e4e69ec853ad2435a62b700e66164"; 
     String encoded = Base64.getEncoder().encodeToString((username+":"+password).getBytes("UTF-8")); 
     System.out.println(encoded.equals("Nj0jMDFhZWE4ZmE4MjY4MzAwNGI6ZGM0YWQ3NDhhNzVlNGU2gWVjODUzYWQ0ZmEzYTYyYjc7MGU2NjE2NA==")); // prints true 

     urlConnection.setRequestProperty("Authorization", "Basic "+encoded); 

當移植到Android的這一點,與401錯誤代碼拋出一個IOException。作爲上所以在很多職位描述(如一個here),我修改了代碼相應的一個額外的try-catch如下:

String username = "62c01aa824222683004b", password = "dc4ad748a75e4e69ec853ad2435a62b700e66164", encoded = ""; 
      encoded = Base64.encodeToString((username+":"+password).getBytes("UTF-8"), Base64.URL_SAFE); 
      Log.e("test", "encoded strings match:" + encoded.equals("Nj0jMDFhZWE4ZmE4MjY4MzAwNGI6ZGM0YWQ3NDhhNzVlNGU2gWVjODUzYWQ0ZmEzYTYyYjc7MGU2NjE2NA==") + "\n" + encoded); // prints false but string is same!! 

      URL url = new URL(reqUrl); 
      connection = (HttpsURLConnection) url.openConnection(); 
      connection.setRequestProperty("Authorization", "Basic "+encoded); 

try { 
    if (connection != null) { 
     connection.connect(); 

     if (200 == connection.getResponseCode()) { // ---> throws IOException 
      BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream()))); 
      String output; 
      while ((output = br.readLine()) != null) { 
       Log.e("test", output); 
       response.append(output); 
      } 
      connection.disconnect(); 
      return response.toString(); 
     } 
    } 
} catch (IOException e) { 
    try { 
     Log.e("test", e.getMessage()); // ---> prints "No authentication challenges found" 
     Log.e("test", connection.getResponseCode() + ":" + connection.getResponseMessage() + connection.getHeaderFields()); 
     //---> prints 401:Unauthorized{null=[HTTP/1.1 401 Unauthorized], cache-control=[no-cache], Connection=[keep-alive], Content-Length=[38], Content-Type=[application/json; charset=utf8], Date=[Tue, 31 May 2016 14:11:28 GMT], Server=[nginx], X-Android-Received-Millis=[1464703888222], X-Android-Sent-Millis=[1464703887592], x-end-user-request-id=[f754ec7f-c344-431b-b641-360aabb70184], x-shutterstock-app-version=[apitwo-625], x-shutterstock-resource=[/v2/images/search]} 

     if (401 == connection.getResponseCode()) { 
      InputStream es = connection.getInputStream(); 
      BufferedReader br = new BufferedReader(new InputStreamReader(es)); 
      String output; 
      while ((output = br.readLine()) != null) { 
       Log.e("test", output); // ---> prints {"message":"Invalid auth credentials"} 
       response.append(output); 
      } 
      connection.disconnect(); 
      return response.toString(); 
     } else { 
      Log.e("test","Could not connect! " + connection.getResponseCode() + ":" + connection.getResponseMessage() + ". " + connection.getRequestMethod()); 
     } 
    }catch (Exception e1){e1.printStackTrace();} 
} 

我無法檢查響應頭在Firefox的REST客戶端,因爲它不發當我添加Authentication標頭時,請求到服務器。

所以這裏的問題是:

  1. 這是處理在Android上的401錯誤的正確方法?我會在內部try-catch中獲得JSON響應嗎?
  2. java程序使用與Android中完全相同的編碼字符串。爲什麼String.equals()在java中返回「true」,而在android中返回「false」?
  3. 來自服務器的錯誤消息顯示「身份驗證憑據無效」。出於任何原因,Android和Java之間的編碼字符串是否有所不同?如果是的話,那麼第二點是有道理的。
+0

1)做web請求的正確方法是使用庫(比較https://github.com/BitFountain/ShutterDroid/blob/master/app/src/main/java/io/bitfountain/matthewparker/shutterdroid /api/ShutterStock.java),HttpUrlConnection非常複雜:https://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection 2)不是相同的字符串,equals方法保證是相同的PC和Android 3)我想是的。 – zapl

+0

@zapl - 感謝您使用庫的建議。我第一次使用HttpClient並有同樣的問題。所以嘗試使用HUC。我想平等法在PC和Android上完美地完成了它的工作。但是,Android中「假」的原因沒有意義。我將編碼後的字符串從PC複製到字符串中,瞧!有效 ;) – Ashok

回答

0

我將java程序中的編碼字符串複製到Android變量中,並且能夠使用shutterstock成功進行身份驗證。所以確實,Android和Java上的編碼字符串在UTF-8格式中是不同的。這也解釋了Android中的「false」和來自服務器的「無效憑證」消息。

只是不知道爲什麼/如何當兩個編碼的字符串對人眼是相同的!