@JsonTypeInfo (use = JsonTypeInfo.Id.CLASS) does not work when the response is returned

I am writing a REST service using Jersey. I have an abstract Promotion class that contains an annotation:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 

Thanks to this, when I return a list of objects:

 @GET @Produces(MediaType.APPLICATION_JSON) @Path("promotions/") public List<Promotion> getClosestPromotions() { List<Promotion> promotions = getPromotions(); //here I get some objects return promotions; } 

I get a Json line with the "@class" field for every object in this list. But the problem is that if I return the answer:

 @GET @Produces(MediaType.APPLICATION_JSON) @Path("promotions/") public Response getClosestPromotions() { List<Promotion> promotions = getPromotions(); //here I get some objects return Response.ok().entity(promotions).build(); } 

I get almost the same list, but without the extra @class field. Why is this and what can I do to get a list with the "@class" field returning the list in Response? And by the way, amazingly, it works when I return a Response with one Promotion object, specified only as an object, and I get this @class field.

+7
source share
3 answers

You might want to try:

 GenericEntity<Collection<Promotion>> genericEntity = new GenericEntity<Collection<Promotion>>(promotions){}; return Response.ok().entity(genericEntity).build(); 
+5
source

Try adding subtype annotation, here is an example that I am using. This can solve your problem by specifying all operational subtypes. Sorry, did not check your example.

 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") @JsonSubTypes({ @JsonSubTypes.Type(value=MetricCollection.class), @JsonSubTypes.Type(value=Column.class), @JsonSubTypes.Type(value=IntegerColumn.class), @JsonSubTypes.Type(value=DoubleColumn.class), @JsonSubTypes.Type(value=StringColumn.class) }) public interface IMetricCollection<T extends IMetric> { ... } 
+2
source

If you used JAXB to generate your classes, you can have something like @XmlElements with different types for parsing a list.

Now, if you also use the same JAXB classes with Jersey / Jackson, you can improve the class metadata by adding @JsonTypeInfo and @JsonSubTypes to describe how to format the list / array name of objects.

While @JsonTypeInfo describes the type to be added, @JsonSubTypes provides options for a nested collection. For example, As.PROPERTY to define an output property, as shown in the example below, where a list of entities that can have elements of different types, including the type itself ("Form") in addition to the other two types, "Field" and "Table" .

 public class Form { @XmlElements({ @XmlElement(name = "field", type = Field.class), @XmlElement(name = "form", type = Form.class), @XmlElement(name = "table", type = Table.class) }) @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "obj") @JsonSubTypes({ @JsonSubTypes.Type(value = Field.class), @JsonSubTypes.Type(value = Form.class), @JsonSubTypes.Type(value = Table.class) }) @Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2013-11-11T02:08:36-08:00", comments = "JAXB RI v2.2.4-2") @JsonProperty("entities") protected List<Object> fieldOrFormOrTable; 

Serializing an object using standard Jack Jackson default serializers with metadata added will be as follows:

  "entities": [ { "obj": "Table", "row": { "id": 1, "fields": [ { "id": "DEBUGARY", "type": "Text", "kind": "user" } ] }, "id": "DBGARRAY" }, { "obj": "field", "id": "IDBG", "type": "Text", "kind": "user" }, ..., ..., ...] 
0
source

All Articles