Bra*_*ugh 31 java mapping jackson
我正在使用Jackson ObjectMapper将一些JSON反序列化为Java类,我们将其称之为PlayerData.我想在类中添加一些逻辑来在PlayerData加载字段后修复一些数据.例如,一些早期的JSON文件用于使用"性别"标志而不是"性别"标志,所以如果性别标志已设置但性别标志未设置,我想将性别字段的值设置为性别字段的值.
是否有某种@PostConstruct或@AfterLoad注释可以粘贴到方法中?或者也许是我可以实现的界面?我没有注意到文档中的一个,但它似乎是一个显而易见的功能.
Mik*_*der 17
通过评论中的链接找到了这一点(credit:fedor.belov).这似乎允许您运行代码后构造.
通过http://jira.codehaus.org/browse/JACKSON-645或 http://jira.codehaus.org/browse/JACKSON-538为最终到此处的人添加评论 并正在寻找一种名为在反序列化器完成之后.通过包含注释和编写使用相同类作为输入和输出的转换器,我能够实现所需的效果.
@JsonDeserialize(converter=MyClassSanitizer.class) // invoked after class is fully deserialized
public class MyClass {
public String field1;
}
import com.fasterxml.jackson.databind.util.StdConverter;
public class MyClassSanitizer extends StdConverter<MyClass,MyClass> {
@Override
public MyClass convert(MyClass var1) {
var1.field1 = munge(var1.field1);
return var1;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您没有使用@JsonCreator,那么Jackson将使用setter和getter方法来设置字段.
因此,如果您定义以下方法,假设您有Sex和Gender枚举:
@JsonProperty("sex")
public void setSex(final Sex sex) {
this.sex = sex;
if (gender == null) {
gender = (sex == Sex.WOMAN) ? Gender.WOMAN : Gender.MAN;
}
}
@JsonProperty("gender")
public void setGender(final Gender gender) {
this.gender = gender;
if (sex == null) {
sex = (gender == Gender.WOMAN) ? Sex.WOMAN : Sex.MAN;
}
}
Run Code Online (Sandbox Code Playgroud)
它会奏效.
更新:您可以在这里找到杰克逊图书馆的所有注释.
Update2:其他解决方案:
class Example {
private final Sex sex;
private final Gender gender;
@JsonCreator
public Example(@JsonProperty("sex") final Sex sex) {
super();
this.sex = sex;
this.gender = getGenderBySex(sex)
}
@JsonFactory
public static Example createExample(@JsonProperty("gender") final Gender gender) {
return new Example(getSexByGender(gender));
}
private static Sex getSexByGender(final Gender) {
return (gender == Gender.WOMAN) ? Sex.WOMAN : Sex.MAN;
}
private static Gender getGenderBySex(final Sex) {
return (sex == Sex.WOMAN) ? Gender.WOMAN : Gender.MAN;
}
}
Run Code Online (Sandbox Code Playgroud)
这不是开箱即用的,但您可以轻松地@JsonPostDeserialize为反序列化后要调用的方法创建注释。
首先,定义注解:
/**
* Annotation for methods to be called directly after deserialization of the object.
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonPostDeserialize {
}
Run Code Online (Sandbox Code Playgroud)
然后,将以下注册和实现代码添加到您的项目中:
public static void addPostDeserializeSupport(ObjectMapper objectMapper) {
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDescription,
JsonDeserializer<?> originalDeserializer) {
return new CustomAnnotationsDeserializer(originalDeserializer, beanDescription);
}
});
objectMapper.registerModule(module);
}
/**
* Class implementing the functionality of the {@link JsonPostDeserialize} annotation.
*/
public class CustomAnnotationsDeserializer extends DelegatingDeserializer {
private final BeanDescription beanDescription;
public CustomAnnotationsDeserializer(JsonDeserializer<?> delegate, BeanDescription beanDescription) {
super(delegate);
this.beanDescription = beanDescription;
}
@Override
protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee) {
return new CustomAnnotationsDeserializer(newDelegatee, beanDescription);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
Object deserializedObject = super.deserialize(p, ctxt);
callPostDeserializeMethods(deserializedObject);
return deserializedObject;
}
private void callPostDeserializeMethods(Object deserializedObject) {
for (AnnotatedMethod method : beanDescription.getClassInfo().memberMethods()) {
if (method.hasAnnotation(JsonPostDeserialize.class)) {
try {
method.callOn(deserializedObject);
} catch (Exception e) {
throw new RuntimeException("Failed to call @JsonPostDeserialize annotated method in class "
+ beanDescription.getClassInfo().getName(), e);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,使用 修改您的ObjectMapper实例addPostDeserializeSupport,它将调用@JsonPostDeserialize反序列化对象的所有带注释的方法。
| 归档时间: |
|
| 查看次数: |
12184 次 |
| 最近记录: |