Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST: how to serialize a java object to JSON in a "shallow" way?

Suppose I have the following JPA entities:

@Entity
public class Inner {
  @Id private Long id;
  private String name;

  // getters/setters
}

@Entity
public class Outer {
  @Id private Long id;
  private String name;
  @ManyToOne private Inner inner;

  // getters/setters
}

Both Spring and java EE have REST implementations with default serializers which will marshall the entities to/from JSON without further coding. But when converting Outer to JSON, both Spring and EE nest a full copy of Inner within it:

// Outer
{
  "id": "1234",
  "name": "MyOuterName",
  "inner": {
    "id": "4321",
    "name": "MyInnerName"
  }
}

This is correct behavior but problematic for my web services, since the object graphs can get deep/complex and can contain circular references. Is there any way to configure the supplied marshaller to marshall the POJOs/entities in a "shallow" way instead without having to create a custom JSON serializer for each one? One custom serializer that works on all entities would be fine. I'd ideally like something like this:

// Outer
{
  "id": "1234",
  "name": "MyOuterName",
  "innerId": "4321"
}

I'd also like it to "unmarshall" the JSON back into the equivalent java object. Bonus kudos if the solution works with both Spring and java EE. Thanks!

like image 302
Alvin Thompson Avatar asked Jul 27 '16 20:07

Alvin Thompson


People also ask

How do you serialize a JSON object?

NET objects as JSON (serialize) To write JSON to a string or to a file, call the JsonSerializer. Serialize method. The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default.

How do you serialize and deserialize JSON object in Java?

Deserialization in the context of Gson means converting a JSON string to an equivalent Java object. In order to do the deserialization, we need a Gson object and call the function fromJson() and pass two parameters i.e. JSON string and expected java type after parsing is finished. Program output.

What is JSON serialize Java?

JSON-Java is a Java serialization/deserialization library. It parses JSON documents into Java objects and generates new JSON documents from the Java classes.

Does Jackson use serializable?

Note that Jackson does not use java. io. Serializable for anything: there is no real value for adding that. It gets ignored.


2 Answers

I had the same problem and ended up using jackson annotations on my Entities to control the serialization:

What you need is @JsonIdentityReference(alwaysAsId=true) to instruct the bean serializer that this reference should be only an ID. You can see an example on my repo:

https://github.com/sashokbg/company-rest-service/blob/master/src/main/java/bg/alexander/model/Order.java

@OneToMany(mappedBy="order", fetch=FetchType.EAGER)
@JsonIdentityReference(alwaysAsId=true) // otherwise first ref as POJO, others as id
private Set<OrderDetail> orderDetails; 

If you want a full control of how your entities are represented as JSON, you can use JsonView to define which field is serialized related to your view.

@JsonView(Views.Public.class) public int id;

@JsonView(Views.Public.class)
public String itemName;

@JsonView(Views.Internal.class)
public String ownerName;

http://www.baeldung.com/jackson-json-view-annotation

Cheers !

like image 66
sashok_bg Avatar answered Oct 26 '22 22:10

sashok_bg


After many problems I give reason to Cássio Mazzochi Molin saying that "the use of entities persistence in your REST API can not be a good idea"

I would do that the business layer transform persistence entities to DTO.

You can do this very easily with libraries like mapstruct

If you still want to continue with this bad practice you can use jackson and customize your jackson mapper

like image 38
Jorge Jiménez Barra Avatar answered Oct 26 '22 23:10

Jorge Jiménez Barra