Gson:帮我解析服务器上的Gson

时间:2018-10-19 08:02:28

标签: android json retrofit

调用API成功时的响应为:

{
    "meta": {
        "timestamp": "2018/05/16 16:43:21",
        "status": "OK"
    },
    "body": {....}

但是在错误情况下调用上述相同API时的响应是:

{
    "meta": {
        "timestamp": "2018/08/16 15:52:45",
        "status": "VALIDATION_ERROR"
    },
    "body": [
        {
            "errorCode": "aaa",
            "errorMessage": "ERROR1",
            "property": "AAA",
            "args": "aa"
        }
    ]
}

您可以看到响应主体是差异,一个是Json数组,一个是json对象,如果我使用改造,该如何解析?

2 个答案:

答案 0 :(得分:0)

您的模型类应该是这样的RootObject

Err typeMismatch(Swift.Dictionary<Swift.String, Any>,     Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))

public class RootObject
{
private Meta meta;

public Meta getMeta() { return this.meta; }

public void setMeta(Meta meta) { this.meta = meta; }

private ArrayList<Body> body;

public ArrayList<Body> getBody() { return this.body; }

public void setBody(ArrayList<Body> body) { this.body = body; }
}

public class Meta
{
private String timestamp;

public String getTimestamp() { return this.timestamp; }

public void setTimestamp(String timestamp) { this.timestamp = timestamp; }

private String status;

public String getStatus() { return this.status; }

public void setStatus(String status) { this.status = status; }
}

答案 1 :(得分:0)

正如@Ridcully所说,这是错误的API设计。由于您无法修改API,因此解决方法是使用继承并将自定义typeAdapter添加到Gson实例。

请注意,SuccessResponseFailureResponse是“ {-1”}。当您对Response类使用typeAdapter时,自定义反序列化器将根据Response的值确定对象应反序列化为SuccessResponse类还是FailureResponse类。

响应父类

Response.meta.status

成功响应儿童班

public class Response{
     private Meta meta;

     public Meta getMeta(){ return meta; }
     public void setMeta(Meta meta){ this.meta = meta; }

}

失败响应子类

public class SuccessResponse extends Response{
     private SuccessContent body;

     public SuccessContent getSuccessContent() { return body; }
     public void setSuccessContent(SuccessContent content) { this.body = content }
 }

成功内容课程

public class FailureResponse extends Response{
     private List<FailureContent> body;

     public List<FailureContent> getBody() { return body; }
     public void setObjList(List<FailureContent> content) { this.body= content; }
}

失败内容类

public class SucessContent{
     //Model class of the success body
}

元类

public class FailureContent{
     private String errorCode;
     private String errorMessage;
     private String property;
     private String args;

     public String getErrorCode() { return errorCode; }
     public void setErrorCode(String errorCode) { this.errorCode = errorCode; }

     public String getErrorMessage() { return errorMessage; }
     public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage;}

     public String getProperty() { return property; }
     public void setProperty(String property) { this.property = property; }

     public String getArgs() { return args; }
     public void setArgs(String args) { this.args = args; }

}

Gson的自定义类型适配器,用于反序列化Response类

public class Meta{
     private String timestamp;
     private String status;

     public String getTimestamp() { return this.timestamp; }
     public void setTimestamp(String timestamp) { this.timestamp = timestamp; }

     public String getStatus() { return this.status; }
     public void setStatus(String status) { this.status = status; }
}

将类型适配器注册到gson并进行改装

public class ResponseBodyAdapter implements JsonDeserializer<Response> {
      @Override
      public Response deserialize (JsonElement json, Type typeOfT, JsonDerializationContext context) throws JsonParseException{
              JsonObject obj = json.getAsJsonObject();
              JsonObject metaObj = obj.getAsJsonObject("meta");
              String status = metaObj.get("status").getAsString();
              if(status.equals("OK")){
                 return context.deserialize(json, SuccessResponse.class);
              }else if(status.equals("VALIDATION_ERROR")){
                 return context.deserialize(json, FailureResponse.class);
              }
              return null;
        } 
 }