2013-02-20 3 views
0

Я пишу небольшое приложение для Android, которое работает с службами REST. Базовая структура ответа является: { результата: «ки/ошибка», сообщения: «некоторая строка», сущности: «либо объект или описание ошибки» }Запрос POST для службы REST в AsyncTask

типа сущности отличается друг время ответа или ошибки. Теперь я вызываю службу из AsyncTask, и мне нужно вернуть результат в поток пользовательского интерфейса.

Я использую библиотеку gson для десриализации JSON с сервера. Проблема в том, что у меня нет возможности узнать, какой у меня ответ (ok или error).

Кроме того, AsyncTask может возвращать только один тип в поток пользовательского интерфейса. Ниже приведен пример того, что я мог придумать. Мне нужно заявить, что я не программист на 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 
} 

}

EDIT: Я изменил сервер вернуть соответствующие HttpCodes (200 успеха, 400 для ошибок), но я до сих пор есть проблемы возвращения двух различных типов объектов из метод doinbackground, один для ошибки и другой для успеха.

+0

У вас есть контроль над службой на стороне сервера? Потому что *** действительно *** должен возвращать соответствующий код состояния для ситуаций с ошибками (некоторый вариант 40x или 50x). Если модификация серверной части не является вариантом, вам придется использовать JsonObject для использования результата. – Perception

+0

Я могу изменить сервер и вернуть соответствующие HttpCodes, но он все равно не даст мне решения о том, как вернуть действительный результат одной рукой и сообщение об ошибке на другом – Dimkin

ответ

1

Правильная служба REST должна включать в себя код ответа HTTP, указывающий состояние обработанного запроса. Если у вас есть контроль над сервисом, я бы рекомендовал изменить его, чтобы вернуть вариант кода 40x или 50x, чтобы сигнализировать об ошибке. Служба должна вернуть только 200 OK, если запрос был успешным. На вашей стороне клиента вы затем проанализируете ответ на основе кода состояния (обычный объект для 200 ok, объект ошибки для чего-либо еще). Псевдокод:

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

+0

Правильно, оно не будет. В этом случае вы можете просто вернуть 'JSONObject' во всех случаях, а затем преобразовать его в соответствующий объект вне метода. – Perception

+0

К сожалению, это произойдет в потоке пользовательского интерфейса. Спасибо – Dimkin