我有一个像这样的简单类:
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注释。我故意忽略了这里的其他注释,它似乎并不相关。
答案 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);