1

In our Spring application we're using Jackson to render the JSON responses of the controllers.

For some endpoints we want to adapt the rendering behaviour and only render the id field of certain objects.

Example

We have 3 objects types (OuterObject, ValueObject, InnerObject). Each has a "id" field beside other fields.

Normal rendering of the JSON object:

{
   "id": 1,
   "name": "outerObject name",
   "valueObject": {
       "id": 11,
       "name": "valueObject 11",
       "innerObj": {
           "id" : 111,
           "name" : "innerObject 111"
       }
   }
}

Special rendering of the JSON object ("name" field of the inner object is skipped)

{
   "id": 1,
   "namne": "obj name",
   "valueObj": {
       "id": 11,
       "name": "valueObj 11",
       "innerObj": {
           "id" : 111         
       }
   }
}

So as you can see, we want to only render the id of certain objects, but only if they are nested. So in the example we want to only render the id field of the inner object.

But if another endpoint would return inner objects then we want to render the whole object.

I saw that Jackson offers many annotations to control the behaviour of how fields get rendered. But as far as I understand them they are all forcing a static behaviour which we don't want.

Because we have many of these records (about 400), we don't want to create a second variation for each objects that only contains the id field. Our approach is to reuse the current logic to build and populate these objects, and throw certain fields away when we serialise the object to a JSON string.

Update

I don't think that @JsonView annotation could solve that issue, as only one view at a time could be used for rendering the response.

Maybe I didn't make the requirements 100% clear.

The OuterObject type and InnerObject type are just examples. We have several of these types (over 400), which can be nested in different combinations. It's not always the case that the InnerObject is nested within the OuterObject. The InnerObject could also be the root of another response of a different endpoint or be nested in another object than OuterObject.

Because of this requirement I don't see how I could solve that using @JsonView annotation. How would I define the views for the case that the OuterObject and InnerObject type can be either root or nested objects. I think I would end up with creating one view per root-to-nested object combination. Having over 400 of these objects this would probably explode in complexity.

Flo
  • 27,355
  • 15
  • 87
  • 125
  • 1
    May be you can use [Jackson Mixins](https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations) and have a mixin for each condition – Smile Dec 10 '19 at 10:16
  • @smile thx for the tip. mixins in combination with a customer serialiser did the job. – Flo Dec 15 '19 at 13:10

1 Answers1

3

You can use @JsonView of Jackson library with Spring and have custom serializations at an endpoint/method level.

Some examples can be found here

Carlos
  • 1,340
  • 1
  • 10
  • 26
  • The problem I see here is the following. Within the custom serialiser I don't know whether the object I'm currently serialising is nested or not. So I don't know whether I should kick out fields or not. – Flo Dec 10 '19 at 11:20
  • so on your endpoint response you do not know which object will be nested and which on the root? Remember JsonView allows multiple views on the same field. I guess with this flexibility you are able to solve it. – Carlos Dec 10 '19 at 14:37
  • Mh, maybe I thought about an approach, that is too generic. Of course I know the type of the root object. But this means I need to annotate all fields in all records with the `@JsonView` annotation. And we have quite a lot of records. – Flo Dec 10 '19 at 14:45
  • ok, regarding your updates to the question I do not know an elegant solution for this. But of course you can manipulate your response directly in your java code and remove unwanted values. – Carlos Dec 11 '19 at 16:59
  • carlos thx for your help anyway. In the meantime we found a nice solution using mixins and a custom serialiser. Unfortunately the question was closed, because someone thought it was already answered somewhere else, so I cannot post the solution we found. I asked for re-opening of the question. – Flo Dec 12 '19 at 09:31