Gson: помогите мне разобрать gson с сервера - PullRequest
0 голосов
/ 19 октября 2018

Ответ при успешном вызове 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"
        }
    ]
}

Вы видите, что тело ответа является diffrence,один - массив Json, другой - объект JSON. Как я могу разобрать, если я использую модификацию?

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Как прокомментировал @Ridcully, это плохой дизайн API.Поскольку вы не можете изменить API, в качестве обходного пути можно использовать наследование и добавление пользовательского typeAdapter к экземпляру Gson.

Обратите внимание, что SuccessResponse и FailureResponse "is-a" 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; }

}

Meta Class

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;
        } 
 }

Регистрация адаптера типа в gson и длядооснащение

Gson gson = new GsonBuilder()
                .registerTypeAdapter(Response.class, new ResponseBodyAdapter ())
                .create();
Retrofit retrofit = new Retrofit.Builder()
                       .baseUrl(baseUrl)
                      .addConverterFactory(GsonConverterFactory.create(gson))
                      .build();
0 голосов
/ 19 октября 2018

класс вашей модели должен быть RootObject следующим образом

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; }
}

public class Body
{
private String errorCode;

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

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

private String errorMessage;

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

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

private String property;

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

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

private String args;

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

public void setArgs(String args) { this.args = args; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...