Retrofit Error: How would I go about deserializing any kind of response from the server?
Retrofit Error: How would I go about deserializing any kind of response from the server?
我正在为 android 使用改造,效果很好,但我想知道是否有更好的解决方案来解决我的问题。
背景
所以我有一个后端服务器,它可能会以 JSON 形式(不是网络)响应与服务器相关的错误消息,例如 "could not find 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;
}
}
}
请注意:根 "data" 对象不存在于此,它在其他地方通过泛型处理,所以我在这个问题中省略了它
然后我将使用改造错误 class getBodyAs 方法将传入的错误映射到此模型。
他们的方法更好吗?请注意后端是我无法控制的。
假设您将 Gson 与 Retrofit 一起使用(这是默认设置)。您可以为您的错误 class 写一个 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 可能会有帮助
我正在为 android 使用改造,效果很好,但我想知道是否有更好的解决方案来解决我的问题。
背景
所以我有一个后端服务器,它可能会以 JSON 形式(不是网络)响应与服务器相关的错误消息,例如 "could not find 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;
}
}
}
请注意:根 "data" 对象不存在于此,它在其他地方通过泛型处理,所以我在这个问题中省略了它
然后我将使用改造错误 class getBodyAs 方法将传入的错误映射到此模型。
他们的方法更好吗?请注意后端是我无法控制的。
假设您将 Gson 与 Retrofit 一起使用(这是默认设置)。您可以为您的错误 class 写一个 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 可能会有帮助