I'm writing a REST service using Jersey. I have an abstract class Promotion that has an annotation:
我正在使用Jersey编写REST服务。我有一个带有注释的抽象类Promotion:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
Thanks to that, 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 string with a "@class" field for every object in that list. But the problem is that if I return a Response:
我为该列表中的每个对象获取一个带有“@class”字段的Json字符串。但问题是,如果我返回一个响应:
@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'm getting almost the same list, but without additional "@class" field. Why is that and what can I do to get a list with "@class" field returning a list in Response? And by the way, surprisingly, it works when I return a Response with one Promotion object only given as an entity and I get that "@class" field.
我得到几乎相同的列表,但没有额外的“@class”字段。为什么这样,我该怎么做才能获得一个带有“@class”字段的列表在Response中返回一个列表?顺便说一句,令人惊讶的是,当我返回一个只有作为实体给出的一个Promotion对象的Response时,它才有用,我得到了那个“@class”字段。
3 个解决方案
#1
5
Maybe you would want to try:
也许你想尝试:
GenericEntity<Collection<Promotion>> genericEntity =
new GenericEntity<Collection<Promotion>>(promotions){};
return Response.ok().entity(genericEntity).build();
#2
2
Try adding the sub types annotation, here is an example that I am using. This may solve your problem by specifying all the operable sub types. Sorry didn't test your exact 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> {
...
}
#3
0
If you used JAXB to generate your classes, you can certainly have something like @XmlElements with different types to parse a List.
如果您使用JAXB生成类,那么您当然可以使用不同类型的@XmlElements来解析List。
Now, if you are also using the same JAXB classes with Jersey/Jackson, you can enhance the metadata of the class by adding @JsonTypeInfo and @JsonSubTypes to describe how to format the name of the List/Array of objects.
现在,如果您还在使用与Jersey / Jackson相同的JAXB类,则可以通过添加@JsonTypeInfo和@JsonSubTypes来增强类的元数据,以描述如何格式化List / Array对象的名称。
While @JsonTypeInfo describes the type to be added, the @JsonSubTypes gives the options of the enclosed collection. For instance, As.PROPERTY to define a property of the output, as displayed in the example below, where a list of entities that can have elements of different types, including the type itself ("Form") in addition to 2 other types "Field" and "Table".
虽然@JsonTypeInfo描述了要添加的类型,但@JsonSubTypes给出了封闭集合的选项。例如,As.PROPERTY用于定义输出的属性,如下例所示,其中可以包含不同类型元素的实体列表,包括类型本身(“Form”)以及其他2种类型“字段“和”表“。
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;
The serialization of the object using Jersey's Jackson default serializers with the added metadata will be the following...
使用Jersey的Jackson默认序列化程序和添加的元数据对象的序列化将如下...
"entities": [
{
"obj": "Table",
"row": {
"id": 1,
"fields": [
{
"id": "DEBUGARY",
"type": "Text",
"kind": "user"
}
]
},
"id": "DBGARRAY"
},
{
"obj": "field",
"id": "IDBG",
"type": "Text",
"kind": "user"
},
..., ..., ...]
#1
5
Maybe you would want to try:
也许你想尝试:
GenericEntity<Collection<Promotion>> genericEntity =
new GenericEntity<Collection<Promotion>>(promotions){};
return Response.ok().entity(genericEntity).build();
#2
2
Try adding the sub types annotation, here is an example that I am using. This may solve your problem by specifying all the operable sub types. Sorry didn't test your exact 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> {
...
}
#3
0
If you used JAXB to generate your classes, you can certainly have something like @XmlElements with different types to parse a List.
如果您使用JAXB生成类,那么您当然可以使用不同类型的@XmlElements来解析List。
Now, if you are also using the same JAXB classes with Jersey/Jackson, you can enhance the metadata of the class by adding @JsonTypeInfo and @JsonSubTypes to describe how to format the name of the List/Array of objects.
现在,如果您还在使用与Jersey / Jackson相同的JAXB类,则可以通过添加@JsonTypeInfo和@JsonSubTypes来增强类的元数据,以描述如何格式化List / Array对象的名称。
While @JsonTypeInfo describes the type to be added, the @JsonSubTypes gives the options of the enclosed collection. For instance, As.PROPERTY to define a property of the output, as displayed in the example below, where a list of entities that can have elements of different types, including the type itself ("Form") in addition to 2 other types "Field" and "Table".
虽然@JsonTypeInfo描述了要添加的类型,但@JsonSubTypes给出了封闭集合的选项。例如,As.PROPERTY用于定义输出的属性,如下例所示,其中可以包含不同类型元素的实体列表,包括类型本身(“Form”)以及其他2种类型“字段“和”表“。
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;
The serialization of the object using Jersey's Jackson default serializers with the added metadata will be the following...
使用Jersey的Jackson默认序列化程序和添加的元数据对象的序列化将如下...
"entities": [
{
"obj": "Table",
"row": {
"id": 1,
"fields": [
{
"id": "DEBUGARY",
"type": "Text",
"kind": "user"
}
]
},
"id": "DBGARRAY"
},
{
"obj": "field",
"id": "IDBG",
"type": "Text",
"kind": "user"
},
..., ..., ...]