Search code examples
springserializationjacksondto

Jackson ignore getter from the class serializing


I'm trying to serialize a class on which I can't touch anything. The problem is I want to ignore some getWhatever() getter methods, but I can't mark the getter method with @JsonIgnore, as that would mean touching the DTO class.

That serialization is being made from a @RestController method at a Spring REST web service, so it would be great if it could be a solution thinking of that.

I have thought of a solution which I don't like... it would be creating a custom serializer for that DTO class I want to serialize, so I can control what gets serialized and what not, and then, from the @RestController, instead of returning the DTO class (which is what I think is more elegant), returning a String after getting the JSON string with an ObjectMapper and forcing the custom serializer.

I don't like that solution as:

  • I would have to create a custom serializer for every DTO class I need to serialize which has getter methods I dont want to serialize
  • I don't like the solution of returning a string representing a JSON which represents the DTO... I prefer to do that transparently and return the DTO class from the method and let the automation of Spring generate that transformation

Thank you in advance... any help will be very appreciated

EDIT (SOLUTION) I have finally adopted this solution thanks to @Cassio Mazzochi Molin idea:

interface FooMixIn {
    @JsonIgnore
    Object getFoo();
    @JsonIgnore
    Object getBar();
}

@Service
public class ServiceFooSerializer extends SimpleModule{
    public ServiceFooSerializer(){
        this.setMixInAnnotation(Foo.class, FooMixIn.class);
    }
}

Solution

  • When modifying the classes is not an option, you can use mix-in annotations.

    You can think of it as kind of aspect-oriented way of adding more annotations during runtime, to augment statically defined ones.

    First define a mix-in annotation interface (a class would do as well):

    public interface FooMixIn {
    
        @JsonIgnore
        Object getWhatever();
    }
    

    Then configure ObjectMapper to use the defined interface as a mix-in for your POJO:

    ObjectMapper mapper = new ObjectMapper().addMixIn(Foo.class, FooMixIn.class); 
    

    Some usage considerations:

    • All annotation sets that Jackson recognizes can be mixed in.
    • All kinds of annotations (member method, static method, field, constructor annotations) can be mixed in.
    • Only method (and field) name and signature are used for matching annotations: access definitions (private, protected, ...) and method implementations are ignored.

    For more details, have a look at the Jackson documentation.