现在我正在学习如何使用Gson
库以Json
格式设置和获取来自webservice的数据,但是它的最佳实践和策略对我来说有点暗,所以我会非常愉快如果有人能解释更多。
我已经创建了一个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调用创建一个实体对象,但我的问题是:
gson.fromJson
会抛出**IllegalStateException: Expected a string but was BEGIN_OBJECT**
我该怎样阻止这个?提前致谢
答案 0 :(得分:0)
<强> 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":"Don\u0027t 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":"Don\u0027t 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上有很多很好的例子,例如this。
我如何处理这种情况:如果数据发送正常则返回特定的Jsonarray;如果没有,返回一个Response对象来检测出错了。我应该使用Custom typeAdapter吗?(示例代码会很棒)
你的意思是你想要解析这种反应吗?第1点的例子表明了这一点。
如果webservice返回一个空响应,gson.fromJson会抛出一个** IllegalStateException:期望一个字符串,但是BEGIN_OBJECT 我该如何防止这种情况?**
JsonParser
/ TypeAdapter
再次成为解决方案。您可以检查JsonElement
是否为null或者是否为基本类型(String,Integer,Boolean)并进行处理。