Java 将请求发布到AsyncTask中的REST服务
我正在编写一些与REST服务一起工作的小型android应用程序。 响应的基本结构是: { 结果:“确定/错误”, 消息:“一些字符串”, 实体:“对象或错误描述” } 无论响应是ok还是error,每次的实体类型都不同。 现在,我从AsyncTask调用服务,需要将结果返回到UI线程 我正在使用gson库从服务器上对JSON进行理想化。问题是我没有能力知道我得到了什么类型的响应(ok或error) 此外,AsyncTask只能向UI线程返回单个类型。下面是一个我能想到的例子。我需要声明我不是java程序员,我可能不知道所有的模式,也许我错过了一些东西 不管怎样,我很高兴能得到任何帮助Java 将请求发布到AsyncTask中的REST服务,java,android,oop,Java,Android,Oop,我正在编写一些与REST服务一起工作的小型android应用程序。 响应的基本结构是: { 结果:“确定/错误”, 消息:“一些字符串”, 实体:“对象或错误描述” } 无论响应是ok还是error,每次的实体类型都不同。 现在,我从AsyncTask调用服务,需要将结果返回到UI线程 我正在使用gson库从服务器上对JSON进行理想化。问题是我没有能力知道我得到了什么类型的响应(ok或error) 此外,AsyncTask只能向UI线程返回单个类型。下面是一个我能想到的例子。我需要声明我不是j
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
}
公共类注册表ProxyAsync扩展异步任务{
@凌驾
受保护对象doInBackground(用户…参数){
试一试{
Gson Gson=新的Gson();
字符串请求=gson.toJson(参数[0]);
HttpClient=new DefaultHttpClient();
HttpPost postAction=新的HttpPost(“http://SomeServiceEndpoint/register");
addHeader(新的BasicHeader(HTTP.CONTENT_TYPE,“application/json”);
setEntity(新的StringEntity(请求));
HttpResponse response=client.execute(postAction);
if(响应!=null){
InputStream=response.getEntity().getContent();
字符串strResult=CharStreams.toString(新的InputStreamReader(stream));
试一试{
UserResponse UserResponse=gson.fromJson(stresult,UserResponse.class);
返回userResponse;
}捕获(例外e){
ErrorResponse=gson.fromJson(strResult,ErrorResponse.class);
返回错误响应;
}
Log.e(“调试”,stresult);
}
}捕获(例外e){
//TODO:处理异常
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onPostExecute(对象结果){
//TODO:执行一些工作
}
}
编辑:
我已经更改了服务器以返回正确的httpcode(200表示成功,400表示错误),但是,我仍然存在从doinbackground方法返回两种不同类型对象的问题,一种用于错误,另一种用于成功 一个适当的REST服务应该包括一个HTTP响应代码,指示已处理请求的状态。如果您可以控制该服务,那么我建议您对其进行修改,以返回40x或50x代码的变体,以表示发生了错误。如果请求成功,服务应仅返回200 OK。在客户端,您将根据状态代码解析响应(正常实体表示200OK,错误实体表示其他任何内容)。伪代码:
if(response.getStatusLine().getStatusCode() == 200) {
UserResponse userResponse = gson.fromJson(strResult, UserResponse.class);
} else {
ErrorResponse errorResponse = gson.fromJson(strResult, ErrorResponse.class);
}
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);
}
如果出于任何原因无法更改服务器端,那么在客户端,必须使用通用的JsonObject
来解析响应。伪代码:
if(response.getStatusLine().getStatusCode() == 200) {
UserResponse userResponse = gson.fromJson(strResult, UserResponse.class);
} else {
ErrorResponse errorResponse = gson.fromJson(strResult, ErrorResponse.class);
}
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);
}
您是否可以控制服务器端服务?因为它确实应该为错误情况返回适当的状态代码(40x或50x的一些变体)。如果修改服务器端不是一个选项,那么您将不得不使用JsonObject来使用结果。我可以修改服务器并返回适当的HttpCodes,但它仍然不能为我提供如何一方面返回有效结果另一方面返回错误消息的解决方案谢谢您的回答。我同意,我可以改变服务器端,但它不会帮助我从方法返回两种不同的类型。这才是真正的问题对,不会的。在这种情况下,您可以在所有情况下返回一个
JSONObject
,然后将其转换为方法之外的适当对象。UI线程会发生什么情况?一旦返回,您将如何处理这些对象?您可以返回一个泛型超类或接口(如Serializable),而不受影响。doinbackground之后的下一个方法位于UI线程,我不能浪费时间解析那里的数据(即使需要毫秒)。但它实际上可以与超类一起工作。