Java 为每个响应改装反序列化器

Java 为每个响应改装反序列化器,java,android,jackson,Java,Android,Jackson,我必须调用一个webservices,它为我查询的每个对象(用户、客户、提供者……)返回如下响应 问题是,当“code”是OK时,我需要获取对象“user”(或customer或其他什么),当“code”是KO时,需要获取字符串消息/错误 我知道这种结构在Web服务中很常见,但我就是找不到处理它们的方法 我想我必须创建一个定制的反序列化程序来完成这项工作,这就是我目前得到的: class UserDeserializer extends JsonDeserializer<User>

我必须调用一个webservices,它为我查询的每个对象(用户、客户、提供者……)返回如下响应

问题是,当“code”是OK时,我需要获取对象“user”(或customer或其他什么),当“code”是KO时,需要获取字符串消息/错误

我知道这种结构在Web服务中很常见,但我就是找不到处理它们的方法

我想我必须创建一个定制的反序列化程序来完成这项工作,这就是我目前得到的:

class UserDeserializer extends JsonDeserializer<User>
{
    @Override
    public User deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
    {
        User user = new User();
        JsonNode node = jp.getCodec().readTree(jp);
        ApiResult result = new ApiResult();

        result.code = (String) node.get("result").get("code").toString();
        result.message = (String) node.get("result").get("message").toString();

        ObjectMapper mapper = new ObjectMapper();
        JsonNode messageObj = mapper.readTree(result.message);

        Iterator<Map.Entry<String, JsonNode>> it = messageObj.fields();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry)it.next();
            Field field = null;
            try {
                field = User.class.getField((String) e.getKey());
                if(field.getType().getName().equals("java.lang.String")) {
                    field.set(user, e.getValue().toString().replace("\"",""));
                }
                if(field.getType().getName().equals("int")) {
                    field.set(user, Integer.parseInt(e.getValue().toString().replace("\"","")));
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }

        return user;
    }
}
类UserDeserializer扩展JsonDeserializer
{
@凌驾
公共用户反序列化(JsonParser jp,反序列化上下文ctxt)引发IOException,JsonProcessingException
{
用户=新用户();
JsonNode节点=jp.getCodec().readTree(jp);
ApiResult结果=新的ApiResult();
result.code=(String)node.get(“result”).get(“code”).toString();
result.message=(String)node.get(“result”).get(“message”).toString();
ObjectMapper mapper=新的ObjectMapper();
JsonNode messageObj=mapper.readTree(result.message);
迭代器it=messageObj.fields();
while(it.hasNext()){
Map.Entry e=(Map.Entry)it.next();
字段=空;
试一试{
field=User.class.getField((字符串)e.getKey());
if(field.getType().getName().equals(“java.lang.String”)){
set(用户,例如getValue().toString().replace(“\”,”);
}
if(field.getType().getName().equals(“int”)){
set(user,Integer.parseInt(例如getValue().toString().replace(“\”,”));
}
}捕获(异常e1){
e1.printStackTrace();
}
}
返回用户;
}
}

有谁能帮我把所有对象的所有Api响应都变成通用的,并在“代码”为“KO”时生成某种消息/错误吗?

基本上,您需要的是这样的东西:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "code")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Result.Error.class, name = "KO"),
        @JsonSubTypes.Type(value = User.class, name = "<your string to determine whether the message is a user or not>") })
static class Result {
    String code;

    Message message;

    interface Message {
        int id();
        // other common properties...
    }

    static class Error implements Message {

        @Override
        public int id() {
            return -1;
        }
    }

    static class User implements Message {

        public int id;
        public String name;

        // other fields...

        @Override
        public int id() {
            return id;
        }
    }

}
{"result":
   {"code":"USER",
    "message": {"<your user>"}
   }
}
// another example
{"result":
   {"code":"PROVIDER",
    "message": {"<your provider>"}
   }
}
或者,您可以在反序列化JSON时简单地指定类型(类)


和往常一样,尝试将字段设置为最终字段/不可变字段。Jackson实现这一点的一种简单方法是通过构造函数,在构造函数中注释参数,并用
@JsonCreator
标记它。如果您使用的是Java 8,那么将非常有用。

消息中的内容是通用的,对吗<代码>{result:{code:“OK”,“message:};顺便说一句,你的JSON是无效的,你不能嵌套像这样的对象,JSON被更正了。我想我是想解释“message”现在是“user”,但当“code”是“OK”时,可能是“customer”或其他任何东西,当“code”是“OK”时,当“code”是“KO”时,可能是字符串“error:……”谢谢,汤姆,这看起来真的是我需要的!
{"result":
   {"code":"USER",
    "message": {"<your user>"}
   }
}
// another example
{"result":
   {"code":"PROVIDER",
    "message": {"<your provider>"}
   }
}