英文:
Deserialize a JSON payload to object base on JSON integer property
问题
Sure, here is the translated code:
我有以下类:
public class Result<T> {
public int code;
public Object meta;
public T data;
}
public class User {
public int id;
public String name;
}
public class Error {
public String field;
public String message;
}
我想要根据 `code` 字段反序列化一个 `JSON` 载荷。如果 `code >= 10`,返回 `Result<ArrayList<Error>>`,否则返回 `Result<User>`
目前,我先将 `JSON` 映射到 `Result<Object>`,然后检查 `code` 字段。基于该值,我进行第二次映射以获取所需的对象。
ObjectMapper mapper = new ObjectMapper();
Result<Object> tempResult = mapper.readValue(json, new TypeReference<Result<Object>>() {});
if (tempResult.code < 10) {
Result<User> result = mapper.readValue(json, new TypeReference<Result<User>>() {});
return result;
} else {
Result<ArrayList<Error>> result = mapper.readValue(json, new TypeReference<Result<ArrayList<Error>>>() {});
return result;
}
有没有一种更优雅的方法在不进行两次反序列化的情况下实现这一点呢?
英文:
I have below classes:
public class Result<T> {
public int code;
public Object meta;
public T data;
}
public class User {
public int id;
public String name;
}
public class Error {
public String field;
public String message;
}
I want to deserialize a JSON
payload based on code
field. If code >= 10
, return Result<ArrayList<Error>>
, otherwise return Result<User>
Currently, I map JSON
to Result<Object>
first, then check the code
field. Based on that value I make second map to desired object.
ObjectMapper mapper = new ObjectMapper();
Result<Object> tempResult = mapper.readValue(json, new TypeReference<Result<Object>>() {});
if (tempResult.code < 10) {
Result<User> result = mapper.readValue(json, new TypeReference<Result<User>>() {});
return result;
} else {
Result<ArrayList<Error>> result = mapper.readValue(json, new TypeReference<Result<ArrayList<Error>>>() {});
return result;
}
Is there an elegant way to do this without deserializing it 2 times?
答案1
得分: 1
你需要实现自定义的 TypeIdResolver
:
class UserTypeIdResolverBase extends TypeIdResolverBase {
@Override
public String idFromValue(Object value) {
throw new IllegalStateException("Not implemented!");
}
@Override
public String idFromValueAndType(Object value, Class<?> suggestedType) {
throw new IllegalStateException("Not implemented!");
}
@Override
public JsonTypeInfo.Id getMechanism() {
return JsonTypeInfo.Id.CUSTOM;
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
if (Integer.parseInt(id) < 10) {
return context.getTypeFactory().constructType(new TypeReference<Result<User>>() {});
}
return context.getTypeFactory().constructType(new TypeReference<Result<List<Error>>>() {});
}
}
并为 Result
类声明:
@JsonTypeInfo(property = "code", use = JsonTypeInfo.Id.CUSTOM, visible = true)
@JsonTypeIdResolver(UserTypeIdResolverBase.class)
class Result<T>
英文:
You need to implement custom TypeIdResolver
:
class UserTypeIdResolverBase extends TypeIdResolverBase {
@Override
public String idFromValue(Object value) {
throw new IllegalStateException("Not implemented!");
}
@Override
public String idFromValueAndType(Object value, Class<?> suggestedType) {
throw new IllegalStateException("Not implemented!");
}
@Override
public JsonTypeInfo.Id getMechanism() {
return JsonTypeInfo.Id.CUSTOM;
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
if (Integer.parseInt(id) < 10) {
return context.getTypeFactory().constructType(new TypeReference<Result<User>>() {});
}
return context.getTypeFactory().constructType(new TypeReference<Result<List<Error>>>() {});
}
}
and declare it for a Result
class:
@JsonTypeInfo(property = "code", use = JsonTypeInfo.Id.CUSTOM, visible = true)
@JsonTypeIdResolver(UserTypeIdResolverBase.class)
class Result<T>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论