现在我正在学习如何使用Gson
库以Json
格式设置和获取Web服务的数据,但它的最佳实践和策略对我来说有点黑暗,所以如果有人能解释更多,我会很高兴。
我创建了一个Entity类来从服务器获取响应实体:
public class Response
{
@SerializedName("Type")
public String Type;
@SerializedName("result")
public String result;
}
在我使用过的AsyncTask类中:
Response _Response = new Response();
try
{
String _url = Global.Url_Request ;
Map<String, String> Params = new HashMap<String, String>();
Params.put("PhoneNumber", this.User_PhoneNumber);
String json = new GsonBuilder().create().toJson(Params, Map.class);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(_url);
httpPost.setEntity(new StringEntity(json));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpResponse getResponse = httpclient.execute(httpPost);
HttpEntity returnEntity = getResponse.getEntity();
is = returnEntity.getContent();
Gson gson = new Gson();
Reader reader = new InputStreamReader(is);
_Response = gson.fromJson(reader, Response.class);
}
catch (Exception e)
{
_Response.Type= "Error";
_Response.result= "Data Is Wrong";
}
return _Response;
它可以很好地为每个不同的http POST调用创建实体对象,但我的问题是:
- 处理具有不同响应对象的Web服务的最佳实践是什么
- 如何处理这种情况:如果数据发送正常,则返回特定的Jsonarray;如果没有,则返回一个Response对象以检测错误。我应该使用自定义类型适配器吗?(示例代码会很棒)
- 如果webservice返回空响应
gson.fromJson
将抛出**IllegalStateException: Expected a string but was BEGIN_OBJECT**
,我该如何防止这种情况发生
提前感谢
1。处理具有不同响应对象的Web服务的最佳实践是什么
我认为这取决于你的控制能力。如果您也对Web服务进行编码,您可以创建一个包含may字段的大容器对象。这些字段中的每一个都是可以在客户端和服务器之间传递的可能响应之一。如果你无法控制服务器可以回复什么,并且可能会有很大的不同,JsonParser是你最好的朋友。您可以使用它来窥探JSON内部,并决定处理响应的正确策略。
让我们为情况一做一个例子。我申报这些类别:
public static class GenericResponse{
public ServerException exception;
public StandardResponse1 responseType1;
public StandardResponse2 responseType2;
@Override
public String toString() {
return "GenericResponse [exception=" + exception + ", responseType1=" + responseType1 + ", responseType2=" + responseType2 + "]";
}
}
public static class ServerException{
public int error;
public String message;
}
public static class StandardResponse1{
public List<Integer> list;
public Date now;
}
有了这种类,我可以解析:
{"responseType1":{"list":[1,2],"now":"Nov 25, 2013 9:26:51 PM"}}
或
{"exception":{"error":-1,"message":"Donu0027t do this at home"}}
例如,如果我从服务器获得第二种类型的响应,则代码为:
GenericResponse out = g.fromJson(fromServerStream, GenericResponse.class);
System.out.println(out);
将返回我:
GenericResponse [exception=stackoverflow.questions.Q20187804$ServerException@1e9d085, responseType1=null, responseType2=null]
你所要做的就是检查你的字段,看看服务器实际回复了什么。
案例二。您无法控制JSON,因此服务器可以回复
[13,17]
或
{"error":-1,"message":"Donu0027t do this at home"}
在这种情况下,您不能像以前那样直接将类类型传递给Gson,但您必须进行检查。我会用JsonParser
来解决这个问题。
Gson g = new Gson();
JsonParser jp = new JsonParser();
JsonElement o = jp.parse(s);
if (o.isJsonArray()){
List<Integer> list = (List) g.fromJson(o, listType1);
System.out.print(list);
}
else{
ServerException e = g.fromJson(s, ServerException.class);
System.out.print(e);
}
使用JsonObject
/JsonArray
等等,就是TypeAdapter
内部发生的事情。在适配器中,您从已经解析的JsonElement开始。SO上有很多很好的例子,比如这个。
如何处理这种情况:如果数据发送正常,则返回特定的Jsonarray;如果没有,则返回一个Response对象以检测错误。我应该使用自定义类型适配器吗?(示例代码会很棒)
你的意思是你想解析这种响应吗?第1点的例子说明了这一点。
如果webservice返回空响应gson.fromJson将抛出**IllegalStateException:应为字符串,但却是BEGIN_OBJECT如何防止这种情况发生?**
CCD_ 9/CCD_。您可以检查JsonElement
是否为null或是否为基元类型(String、Integer、Boolean)并进行处理。