I have customly serialized my object which is represented by this class:
public class Product {
private Long id;
private String name;
private Unit defaultUnit;
private Section section;
}
Serialization:
@Override
public void serialize(Product product, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumberField("id", product.getId());
jsonGenerator.writeStringField("name", product.getName());
jsonGenerator.writeStringField("defaultUnit", product.getDefaultUnit().toString());
jsonGenerator.writeObjectField("section", product.getSection());
}
However this produces an error which as I understand means that the default serializer has created a key and I have to provide it with a value:
Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Can not write a field name, expecting a value; nested exception is com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value]
Now it is obvious that the solution is to wrap the fields adding
jsonGenerator.writeStartObject();
jsonGenerator.writeEndObject();
This however results in generating entity wrapped in "content" object:
"content": {
"id": 1,
"name": "Product",
"defaultUnit": "Unit",
"section": {
"name": "Section"
}
}
My question is whether it is possible to write the entity unwrapped that is without the "content" key.
The following is all the code associated with Product: Product.java
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@JsonDeserialize(using = ProductDeserializer.class)
@JsonSerialize(using = ProductSerializer.class)
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NonNull
private String name;
@ManyToOne
@NonNull
private Unit defaultUnit;
@ManyToOne
@NonNull
private Section section;
}
ProductExcerpt.java
@Projection(name = "productExcerpt", types = {Product.class})
public interface ProductExcerpt {
String getName();
@Value("#{target.defaultUnit.toString()}")
String getDefaultUnit();
SectionExcerpt getSection();
}
ProductRepository.java
@RepositoryRestResource(excerptProjection = ProductExcerpt.class)
@CrossOrigin
public interface ProductRepository extends JpaRepository<Product, Long> {
}
ProductSerializer.java
public class ProductSerializer extends StdSerializer<Product> {
ProductSerializer(){
super(Product.class);
}
@Override
public void serialize(Product product, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeNumberField("id", product.getId());
jsonGenerator.writeStringField("name", product.getName());
jsonGenerator.writeStringField("defaultUnit", product.getDefaultUnit().toString());
jsonGenerator.writeObjectField("section", product.getSection());
jsonGenerator.writeEndObject();
}
}
There is also ProductDeserializer class however I think that it is irrevelant in this case. I do not have a Controller configured beacause as far as I am concerned there is no need while using spring-data-rest.