将JSON载荷反序列化为对象,基于JSON整数属性。

huangapple go评论94阅读模式
英文:

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&lt;T&gt; {
	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 &gt;= 10, return Result&lt;ArrayList&lt;Error&gt;&gt;, otherwise return Result&lt;User&gt;

Currently, I map JSON to Result&lt;Object&gt; first, then check the code field. Based on that value I make second map to desired object.

ObjectMapper mapper = new ObjectMapper();
Result&lt;Object&gt; tempResult = mapper.readValue(json, new TypeReference&lt;Result&lt;Object&gt;&gt;() {});

if (tempResult.code &lt; 10) {    
    Result&lt;User&gt; result = mapper.readValue(json, new TypeReference&lt;Result&lt;User&gt;&gt;() {});
	return result;
} else {
    Result&lt;ArrayList&lt;Error&gt;&gt; result = mapper.readValue(json, new TypeReference&lt;Result&lt;ArrayList&lt;Error&gt;&gt;&gt;() {});
	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(&quot;Not implemented!&quot;);
    }

    @Override
    public String idFromValueAndType(Object value, Class&lt;?&gt; suggestedType) {
        throw new IllegalStateException(&quot;Not implemented!&quot;);
    }

    @Override
    public JsonTypeInfo.Id getMechanism() {
        return JsonTypeInfo.Id.CUSTOM;
    }

    @Override
    public JavaType typeFromId(DatabindContext context, String id) {
        if (Integer.parseInt(id) &lt; 10) {
            return context.getTypeFactory().constructType(new TypeReference&lt;Result&lt;User&gt;&gt;() {});
        }
        return context.getTypeFactory().constructType(new TypeReference&lt;Result&lt;List&lt;Error&gt;&gt;&gt;() {});
    }
}

and declare it for a Result class:

@JsonTypeInfo(property = &quot;code&quot;, use = JsonTypeInfo.Id.CUSTOM, visible = true)
@JsonTypeIdResolver(UserTypeIdResolverBase.class)
class Result&lt;T&gt;

huangapple
  • 本文由 发表于 2020年9月17日 13:12:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63931645.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定