改造错误:如何从服务器反序列化任何类型的响应?

时间:2015-05-07 20:06:08

标签: android json retrofit

我正在使用android的改造一直很好但我想知道是否有更好的解决方案来解决我的问题。

背景

所以我有一个后端服务器可能会以JSON格式(不是网络)响应服务器相关的错误消息,例如“找不到ID X”等。

看起来像这样

{
      "data": {
        "errors": {
          "base": [
            "You could do the following because of blah blah"
          ]
        }
      }
    }

所以问题是JSON错误对象包含数组“base”可能不被称为“base”它可能被称为其他完全不同的。我的后端有很多种错误响应消息名称,不能轻易改变。

我的问题是,可以在不必事先知道其名称的情况下对此JSON数组进行反序列化。

到目前为止,我一直在这样做,这正在成为一种痛苦。

public class MyRetrofitError
{

    @SerializedName(JsonConstants.ERROR_KEY)
    private Errors errors;


    public Errors getErrors() {
        return errors;
    }

    public void setErrors(Errors errors) {
        this.errors = errors;
    }

    public static class Errors
    {
        private String errorMessage;
        private ErrorCodes errorCodes;

        public enum ErrorCodes{
            BOOKED_OVER_20,PROMO_CODE_FAILED;
        }

        @SerializedName("booked_over")
        private ArrayList<String> bookedOver= new ArrayList<String>();

        @SerializedName("promo_fail")
        private ArrayList<String> promoFailed= new ArrayList<String>();

        public String getErrorMessage() {
            if(promoFailed!= null && promoFailed.size() > 0) {setErrorMessage(promoFailed().get(0)); errorCodes = ErrorCodes.PROMO_CODE_FAILED;}
            if(bookedOver!= null && bookedOver.size() > 0){setErrorMessage(bookedOver().get(0)); errorCodes = ErrorCodes.BOOKED_OVER_20; }

            return errorMessage;
        }

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

        public ErrorCodes getErrorCodes() {
            return errorCodes;
        }
    }


}

请注意:根“数据”对象不存在于此,其处理通过泛型的地方所以我省略了这个问题

然后我会使用改进的Error类getBodyAs方法将传入错误映射到此模型。

他们是更好的方式吗?请注意后端是我无法控制的。

1 个答案:

答案 0 :(得分:1)

假设您正在使用Gson和Retrofit(默认情况下)。你可以为你的错误类写一个Custom Gson Deserializer并保存你想要的。

这是一个快速举例,为您提供想法(未经测试)

// Possible error class
public static class Errors {
  Map<String, List<String>> errors;
  public void addErrors(String key, List<String> issues) {
     errors.put(key, issues);
  }
}

class ErrorDeserialzer implements JsonDeserializer<Errors> {

  @Override
  public Errors deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
  throws JsonParseException {
    Set<Map.Entry<String, JsonElement>> entries = jsonElement.getAsJsonObject().entrySet();
    for (Map.Entry<String, JsonElement> issues : entries) {
        List<String> values = new ArrayList<>();
        for (JsonElement value : issues.getValue().getAsJsonArray()) {
            values.add(value.getAsString());   
        }
        errors.add(issues.getKey(), values);
    }
    return errors;
  }
}

修改 我也刚刚发现了link可能有所帮助