Search code examples
springserializationjacksonfasterxmlspring-restcontroller

spring rest dynamically exclude Object properties from serialization


i want to exclude specific properties of spring rest response body. after hours of googling around i found this: http://www.jroller.com/RickHigh/entry/filtering_json_feeds_from_spring due to its date i like to ask if there is something more up-to-date for jackson and or fasterxml. JsonView doesnt fit my requirements as i need to have such case covered:

if A is the set of all my attributes: one time i need to expose B with B ⊂ A. another time C with C ⊂ A. And B ∩ C != ∅

this would cause complex view declarations as well as annotating every class and might not be possible as well in some cases. so what i would like to do is something similar to this:

@RequestMapping("/test1")
@JsonIgnoreProperties( { "property1"})
public TestObject test1(HttpRequest request){
    return new TestObject();
}

@RequestMapping("/test2")
@JsonIgnoreProperties( { "property2"})
public TestObject test1(HttpRequest request){
    return new TestObject();
}

with output:

{property2:ipsum,property3:dolor}

{property1:lorem,property3:dolor}

Solution

  • In my opinion Jackson View is what you need.

    You have to define three interfaces which should cover all properties:

    1. Public - all common properties.
    2. A - properties which belong to set A.
    3. B - properties which belong to set B.

    Example interfaces:

      class Views {
                static class Public { }
                static class A extends Public { }
                static class B extends Public { }
      }
    

    Assume that your POJO class looks like this:

    class TestObject {
                @JsonView(Views.A.class) String property1;
                @JsonView(Views.B.class) String property2;
                @JsonView(Views.Public.class) String property3;
      }
    

    Now, your controller should contain below methods with annotations:

    @RequestMapping("/test1")
    @JsonView(Views.B.class)
    public TestObject test1(HttpRequest request){
        return new TestObject();
    }
    
    @RequestMapping("/test2")
    @JsonView(Views.A.class)
    public TestObject test2(HttpRequest request){
        return new TestObject();
    }
    

    All of this I has created without testing. Only by reading documentation but it should work for you. I am sure that similar solution worked for me once.