Issue
I have a need to have two different ObjectMapper
in the application.
Pojo I am working with:
public class Student {
private String name;
private Integer age;
@HideThisField
private String grade;
// getters & setters..
}
One is the out of the box configuration based ObjectMapper
as below:
@Bean("objectMapper")
public ObjectMapper getRegularObjectMapper() {
//With some configurations
return new ObjectMapper();
}
I need another ObjectMapper
that while serializing ignores a few fields for all objects based on an annotation on a field.
@Bean("customObjectMapper")
public ObjectMapper getCustomObjectMapper() {
// This is where i want to ignore the fields with @HideThisField
return new ObjectMapper();
}
Output of the two mappers:
objectMapper.writeValuesAsString(someStudent)
prints:
{"name": ""student1", age: 10, "grade": "A+"}
customObjectMapper.writeValuesAsString(someStudent)
prints:
{"name": ""student1", age: 10}
Solution
JacksonAnnotationIntrospector
handles standard Jackson
annotations. Overriding the hasIgnoreMarker
method, you can make it work according to your own annotation.
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.*;
import java.lang.annotation.*;
public class StudentExample {
public static void main(String[] args) throws JsonProcessingException {
Student student = new Student();
student.setName("Student 1");
student.setAge(10);
student.setGrade("A+");
String st1 = getRegularObjectMapper().writeValueAsString(student);
String st2 = getCustomObjectMapper().writeValueAsString(student);
System.out.println(st1);
System.out.println(st2);
}
public static ObjectMapper getRegularObjectMapper() {
return new ObjectMapper();
}
public static ObjectMapper getCustomObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
if (_findAnnotation(m, HideThisField.class) != null)
return true;
return false;
}
});
return objectMapper;
}
}
class Student {
private String name;
private Integer age;
@HideThisField
private String grade;
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface HideThisField {}
The console output is:
{"name":"Student 1","age":10,"grade":"A+"}
{"name":"Student 1","age":10}
getCustomObjectMapper()
don't skips JsonIgnore
annotations because you override the standard, if you want, you need to add this to the if block.
Answered By - İsmail Y.
Answer Checked By - Katrina (JavaFixing Volunteer)