0

I am developing a Spring Boot web application that exposes REST APIs and I have trouble with JSON Serialization.

Let's say I have two classes A and B, that are in a one-to-many bidirectional relationship.

This means that I have something like this:

public class A {
    private List<B> bList;
    ...
}

and

public class B {
    private A owner;
    ...
}

When it comes to JSON serialize this, of course there is a loop.

And this is my problem:

  • In API methods that focus on A (e.g. "give me the list of all As in the DB"), I would like a JSON serialization in which:
    • A objects do contain the list of Bs
    • B objects do not contain their A owner
  • In API methods that focus on B (e.g. "give me the list of all Bs in the DB"), I would like a JSON serialization in which:
    • A objects do not contain the list of their Bs
    • B objects do contain their A owner

I believe I could get it to work with @JsonView annotations, but I do not think it is an elegant solution. In my application (which has more than two classes) I'd need to create and manage at least 4 or 5 JsonViews: so in my model classes, for each attribute I'd have to manage a messy bunch of @JsonView annotations. On the contrary, I believe that model classes should not be aware of the fact that they have different JSON representations depending on the API method.

I searched how to use custom JSON serializers, and found that Jackson allows to do that with its SimpleModule. However it seems that the SimpleModule does not allow to choose which serializer to use on a case-by-case basis (it just always uses the last added Serializer).

So I am a bit clueless now. Does anybody know a clean way to allow the Controllers choose how to serialize a Class?

Lorelorelore
  • 3,335
  • 8
  • 29
  • 40
Andrea Rossi
  • 981
  • 1
  • 10
  • 23

3 Answers3

0

I think you should use DTO here, you could use different DTO for different endpoints, and you could choose which fields you want to include or exclude. Also, you could decorate them if you need so.

Here you have a list of benefits of using DTO in your endpoints: REST API - DTOs or not?

Ignasi
  • 5,887
  • 7
  • 45
  • 81
0

Use @JsonIdentityInfo

Your question has answer over here: Jackson - serialization of entities with birectional relationships (avoiding cycles)

sinujohn
  • 2,506
  • 3
  • 21
  • 26
0

You can use the @JsonIdentityInfo annotation with entities or use @JsonManagedReference, @JsonBackReference.

You can even ignore one side of the relationship with @JsonIgnore or @JsonView.

If you want to mange serialization / unserialization by yourself, use custom implementations (e.g. with @JsonDeserialize).

Eugen provided a nice tutorial on this.

Frito
  • 446
  • 2
  • 12
  • As I said I need to serialize objects in different ways depending on the API method. So I guess @JsonManagedReference, JsonBackReference and JsonIgnore are out of discussion, as they always serialize in the same way, independently from the specific call (am I right on this?). Even a single custom serializer is not enough: I need multiple ones. So I JsonDeserialize is not useful either. As I said JsonView would solve the problem, but in a very messy way. I think model classes should know nothing of how they get serialized, especially if the serialization logic is complex. – Andrea Rossi Oct 16 '18 at 10:05
  • The first annotation mentioned is probably the best matching one, in regard to your exact usecase. I mentioned the other possibilities, too, since they might be still an option, at least for other users with similar problems. – Frito Oct 16 '18 at 12:41