2013-02-20 113 views
0

我在寫一些小的Android應用程序,與REST服務一起使用。 響應的基本結構是: { 結果:「OK /錯誤」, 消息:「一些字符串」, 實體:「任一對象或錯誤描述」 }POST請求到REST服務在AsyncTask

的實體類型是不同的各時間響應是否正確或錯誤。 現在,我從AsyncTask調用服務,並且需要將結果返回給UI線程。

我使用GSON庫從服務器desirialize的JSON。問題是我沒有能力知道我有什麼類型的迴應(好或錯誤)。

此外,的AsyncTask只能返回單一類型到UI線程。以下是我能想出的一個例子。我需要說明我不是一個Java程序員,我可能不知道所有的模式,也許我錯過了一些東西。

無論如何,我會很高興的任何幫助。

public class RegisterProxyAsync extends AsyncTask<User, String, Object> { 

@Override 
protected Object doInBackground(User... params) { 
    try { 
     Gson gson = new Gson(); 
     String request = gson.toJson(params[0]); 

     HttpClient client = new DefaultHttpClient(); 
     HttpPost postAction = new HttpPost("http://SomeServiceEndpoint/register"); 
     postAction.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); 
     postAction.setEntity(new StringEntity(request)); 

     HttpResponse response = client.execute(postAction); 
     if (response != null) { 
      InputStream stream = response.getEntity().getContent(); 
      String strResult = CharStreams.toString(new InputStreamReader(stream)); 
      try { 
       UserResponse userResponse = gson.fromJson(strResult, UserResponse.class); 
       return userResponse; 
      } catch (Exception e) { 
       ErrorResponse errorResponse = gson.fromJson(strResult, ErrorResponse.class); 
       return errorResponse; 
      } 

      Log.e("debug", strResult); 
     } 
    } catch (Exception e) { 
     // TODO:Handle exception 
     e.printStackTrace(); 
    } 

    return null; 
} 

@Override 
protected void onPostExecute(Object result) { 
    // TODO: execute some work 
} 

}

編輯: 我已經改變了服務器返回正確HttpCodes(200成功,400錯誤),但我仍然有從返回兩種不同類型的對象的問題doinbackground方法,一個用於錯誤,另一個用於成功。

+0

您是否擁有對服務器端服務的控制權?因爲它***真的應該爲錯誤情況返回一個適當的狀態碼(一些40x或50x的變體)。如果修改服務器端不是一個選項,那麼你將不得不使用JsonObject來消費結果。 – Perception 2013-02-20 20:42:52

+0

我可以修改服務器,並返回相應的HttpCodes,但是,它仍然不會給我一個有關如何在其他 – Dimkin 2013-02-20 20:45:55

回答

1

一個適當的REST服務應該包括指示處理請求的狀態的HTTP響應代碼。如果您對服務有控制權,那麼我會建議修改它以返回40x或50x代碼的變體,以表示發生了錯誤。如果請求成功,服務應該只返回200 OK。在你的客戶端,你會根據狀態碼解析響應(正常實體爲200,錯誤實體爲其他)。僞代碼:

if(response.getStatusLine().getStatusCode() == 200) { 
    UserResponse userResponse = gson.fromJson(strResult, UserResponse.class); 
} else { 
    ErrorResponse errorResponse = gson.fromJson(strResult, ErrorResponse.class); 
} 

如果你無法改變不管出於什麼原因在服務器端,然後在您的客戶端,你將不得不使用一個通用JsonObject解析響應。僞代碼:

JSONObject jsonObj = new JSONObject(strResult); 
if("ok".equals(jsonObj.get("result")) { 
    return gson.fromJson(jsonObj.toString(), UserResponse.class); 
} else { 
    return gson.fromJson(jsonObj.toString(), ErrorResponse.class); 
} 
+0

感謝您的回答返回有效的結果,一個單手和錯誤信息的解決方案。我同意,我可以改變服務器端,但它不會幫助我需要從該方法返回兩種不同的類型。這就是真正的問題 – Dimkin 2013-02-20 20:50:02

+0

對,它不會。在這種情況下,您可以在所有情況下返回一個'JSONObject',然後將其轉換爲方法外的適當對象。 – Perception 2013-02-20 20:52:50

+0

不幸的是它會在UI線程中發生。謝謝 – Dimkin 2013-02-20 20:58:10