Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson Mapper post-construct

I am using the Jackson ObjectMapper to deserialize some JSON into a Java class, which we'll call PlayerData. I would like to add a bit of logic to the PlayerData class to fix up some data after the fields have been loaded in. For example, some early JSON files used to use a "sex" flag instead of a "gender" falg, so if the sex flag is set but the gender flag is not set, I'd like to set the value of the gender field to be the value of the sex field.

Is there some sort of @PostConstruct or @AfterLoad annotation that I could affix to a method? Or perhaps an interface that I could implement? I didn't notice one in the documentation, but it seemed like an obvious feature.

like image 890
Brandon Yarbrough Avatar asked Jul 26 '11 18:07

Brandon Yarbrough


2 Answers

Found this thru a link in the comments (credit: fedor.belov). This appears to allow you to run code post construct.

Adding a comment for people who end up here via http://jira.codehaus.org/browse/JACKSON-645 or http://jira.codehaus.org/browse/JACKSON-538 and are looking for a method which is called after a deserializer completes. I was able to achieve the desired effect by including an annotation and writing a converter which uses the same class as input and output.

@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;   } } 
like image 168
Mike Rylander Avatar answered Sep 18 '22 12:09

Mike Rylander


If you're not using the @JsonCreator, then Jackson will use the setter and getter methods to set the fields.

So if you define the following methods assuming that you have Sex and Gender enums:

@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;   } } 

it would work.

Update: You can find all of the annotations of Jackson library here.

Update2: Other solution:

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;   }  } 
like image 31
KARASZI István Avatar answered Sep 20 '22 12:09

KARASZI István