杰克逊反序列化只提供一个@Id作为字符串

时间:2015-07-07 16:21:39

标签: java hibernate jackson deserialization

我有一个像这样的简单类:

public class User {
  @Id
  private Integer id;
  private String name;
   ...
}

杰克逊可以用这个JSON显然直接反序列化:

{
  "id": 123  // with int
  "name": "bli",
}

{
  "id": "123"  // with String
  "name": "bli",
}

但是,默认情况下,@Id注释似乎只通过提供Id来反序列化User类。例如,假设我有另一个包含Search的小组User

public class Search {
  private String title;
  private User user;
   ...
}

这有效:

{
  "title": "blo",
  "user": 123 // with int
}

但不是这样:

{
  "title": "blo",
  "user": "123" // with String
}

是否有办法通过仅将id作为String提供来反序列化类?

注意:我的所有类都通过Hibernate绑定到Postgres数据库。因此@Id注释。我故意忽略了这里的其他注释,它似乎并不相关。

1 个答案:

答案 0 :(得分:0)

好吧,所以自定义反序列化器将是:

public class UserDeserializer extends StdDeserializer<User> implements ResolvableDeserializer {

    private final JsonDeserializer<?> defaultDeserializer;

    public UserDeserializer(JsonDeserializer<?> defaultDeserializer) {
        super(User.class);
        this.defaultDeserializer = defaultDeserializer;
    }

    @Override
    public User deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
        String text = jp.getText();
        JsonToken currentToken = jp.getCurrentToken();

        if(!currentToken.equals(JsonToken.VALUE_NUMBER_INT) && !text.startsWith("{")) {
            try{
                return new User(Integer.parseInt(text));
            }
            catch(Exception e) {
                throw new IOException("Unable to process '" + text + "'. Expecting an ID as an integer or a full json representation of the object.");
            }

        }

        return (User) defaultDeserializer.deserialize(jp, dc);
    }

    @Override
    public void resolve(DeserializationContext ctxt) throws JsonMappingException {
        ((ResolvableDeserializer) defaultDeserializer).resolve(ctxt);
    }
}
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
    @Override
    public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
        if (beanDesc.getBeanClass() == User.class)
            return new UserDeserializer(deserializer);
        return deserializer;
    }
});
environment.getObjectMapper().registerModule(module);