2012-07-28 90 views
4

我的Android應用程序使用HttpClient/HttpGet來訪問REST API。我還設置了:Android:org.apache.http.NoHttpResponseException:目標服務器未能響應

httpGet.addHeader("Authorization", "Basic " + basicAuth); 

...它向服務器發送Base64編碼的「用戶名:密碼」。爲了測試,我只使用HTTP而不使用HTTPS連接到服務器。

每當我呼籲HttpClient的「執行」,我收到以下異常:

07-28 10:51:39.610: I/# PA #(12112): org.apache.http.NoHttpResponseException: The target server failed to respond 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:85) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:174) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:180) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:235) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:259) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:279) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:428) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
07-28 10:51:39.610: I/# PA #(12112): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
07-28 10:51:39.610: I/# PA #(12112): at org.thomasamsler.android.app.tasks.HttpGetTask.doInBackground(HttpGetTask.java:87) 
07-28 10:51:39.610: I/# PA #(12112): at org.foo.android.app.tasks.HttpGetTask.doInBackground(HttpGetTask.java:1) 
07-28 10:51:39.610: I/# PA #(12112): at android.os.AsyncTask$2.call(AsyncTask.java:264) 
07-28 10:51:39.610: I/# PA #(12112): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
07-28 10:51:39.610: I/# PA #(12112): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
07-28 10:51:39.610: I/# PA #(12112): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) 
07-28 10:51:39.610: I/# PA #(12112): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
07-28 10:51:39.610: I/# PA #(12112): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
07-28 10:51:39.610: I/# PA #(12112): at java.lang.Thread.run(Thread.java:856) 

注:

其實,我有不同的託管服務提供商三個發展服務器。當連接到其中兩個,我得到上述錯誤。連接到第三臺服務器時,一切正常。另外,其他GET和POST請求在所有三個開發服務器上都可以正常工作。

所以我想知道是否有什麼具體的HTTP GET設置基本身份驗證標題。

我也可以使用「curl」調用REST API,而不會出現任何問題。

代碼:

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 

import android.os.AsyncTask; 
import android.util.Log; 

public class HttpGetTask extends AsyncTask<HttpGetRequestArgs, Void, String> implements AppConstants { 

    private HttpTaskNotifier mNotifier; 

    private HttpResponse mHttpResponse; 
    private int mHttpStatusCodeOk; 
    private int mHttpStatusCode; 
    private int mErrorCode = AppConstants.NO_ERROR; 

    public HttpGetTask(int httpStatusCodeOk, HttpTaskNotifier notifier) { 

     mNotifier = notifier; 
     mHttpStatusCodeOk = httpStatusCodeOk; 
    } 

    @Override 
    protected String doInBackground(HttpGetRequestArgs... args) { 

     HttpGetRequestArgs httpGetRequestArgs = args[0]; 

     HttpClient httpClient = new DefaultHttpClient(); 
     HttpGet httpGet = null; 

     try { 

      httpGet = new HttpGet(httpGetRequestArgs.getUrl()); 

      String apiKey = httpGetRequestArgs.getApiKey(); 

      if (null != apiKey && !"".equals(apiKey)) { 

       httpGet.addHeader("Authorization", "ApiKey " + apiKey); 
      } 

      String basicAuth = httpGetRequestArgs.getBasicAuth(); 

      if (null != basicAuth && !"".equals(basicAuth)) { 

       httpGet.addHeader("Authorization", "Basic " + basicAuth); 
      } 

     } 
     catch (IllegalArgumentException e) { 

      Log.e(LOG_TAG, "EXCEPTION", e); 
      return null; 
     } 

     try { 

      mHttpResponse = httpClient.execute(httpGet); 
     } 
     catch (ClientProtocolException e) { 

      mErrorCode = AppConstants.REST_ERROR; 
      return null; 
     } 
     catch (IOException e) { 

      mErrorCode = AppConstants.REST_ERROR; 
      return null; 
     } 
     catch (IllegalArgumentException iae) { 

      mErrorCode = AppConstants.REST_ERROR; 
      return null; 
     } 

     if (null == mHttpResponse) { 

      mErrorCode = AppConstants.REST_ERROR; 
      return null; 
     } 

     mHttpStatusCode = mHttpResponse.getStatusLine().getStatusCode(); 

     if (mHttpStatusCodeOk != mHttpStatusCode) { 

      mErrorCode = AppConstants.REST_ERROR; 
      return null; 
     } 

     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     HttpEntity httpEntity = mHttpResponse.getEntity(); 

     if (null == httpEntity) { 

      mErrorCode = AppConstants.REST_ERROR; 
      return null; 
     } 

     try { 

      httpEntity.writeTo(out); 
      out.close(); 
     } 
     catch (IOException ioe) { 

      mErrorCode = AppConstants.REST_ERROR; 
      return null; 
     } 

     return out.toString(); 
    } 

    @Override 
    protected void onPostExecute(String content) { 

     if (AppConstants.NO_ERROR != mErrorCode) { 

      mNotifier.onError(mErrorCode); 
     } 

     mNotifier.doProcess(content); 
    } 

    @Override 
    protected void onCancelled() { 

     mNotifier.doCancel(); 
    } 
} 
+0

我忘了提及以下內容:發生異常時,它看起來好像客戶端實際上試圖連續執行4次REST調用。當REST調用執行時,我在服務器上添加了一條調試語句,並且我看到調試消息連續出現4次。 – tamsler 2012-07-28 19:02:21

回答

8

我終於想通了,問題是什麼。當我執行用戶名和密碼的Base64編碼時,我使用Base64.encodeToString(...)的錯誤標誌。所以我改變falg:

FROM:

basicAuth = Base64.encodeToString(basicAuth.getBytes(), Base64.DEFAULT); 

TO:

basicAuth = Base64.encodeToString(basicAuth.getBytes(), Base64.NO_WRAP); 

...一切工作就好了。

+0

我也有類似的問題。但我的錯誤是我使用http服務器地址是https。改變我的問題 – SKT 2012-12-13 10:58:51