Java @返回响应时JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)不工作

Java @返回响应时JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)不工作,java,json,rest,jersey,jackson,Java,Json,Rest,Jersey,Jackson,我正在用Jersey写一个休息服务。我有一个抽象类升级,它有一个注释: @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 因此,当我返回对象列表时: @GET @Produces(MediaType.APPLICATION_JSON) @Path("promotions/") public List<Promotion> getClosestPromotions() { List<Promotion> promotions = get

我正在用Jersey写一个休息服务。我有一个抽象类升级,它有一个注释:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
因此,当我返回对象列表时:

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

return promotions;
}
@GET
@产生(MediaType.APPLICATION_JSON)
@路径(“促销/”)
公共列表getClosesPromotions(){
List promotions=getPromotions();//这里有一些对象
退货促销;
}
我得到一个Json字符串,该列表中的每个对象都有一个“@class”字段。但问题是,如果我返回响应:

@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();
}
@GET
@产生(MediaType.APPLICATION_JSON)
@路径(“促销/”)
公共响应GetClosesPromotions(){
List promotions=getPromotions();//这里有一些对象
返回Response.ok().entity(promotions.build();
}
我得到了几乎相同的列表,但没有额外的“@class”字段。 为什么会这样?我该怎么做才能得到一个“@class”字段返回列表作为响应的列表?
顺便说一句,令人惊讶的是,当我返回一个只作为实体给出的升级对象的响应时,它会起作用,并且我得到“@class”字段。

也许你想试试:

GenericEntity<Collection<Promotion>> genericEntity = 
           new GenericEntity<Collection<Promotion>>(promotions){};
return Response.ok().entity(genericEntity).build();
GenericEntity GenericEntity=
新一般实体(晋升){};
返回Response.ok().entity(genericeentity.build();

尝试添加子类型注释,下面是我正在使用的示例。这可以通过指定所有可操作的子类型来解决您的问题。抱歉,没有测试您的确切示例

@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> {
...
}
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“@CLASS”)
@JsonSubTypes({
@JsonSubTypes.Type(值=MetricCollection.class),
@JsonSubTypes.Type(值=Column.class),
@JsonSubTypes.Type(值=IntegerColumn.class),
@JsonSubTypes.Type(值=DoubleColumn.class),
@JsonSubTypes.Type(值=StringColumn.class)
})
公共接口集合{
...
}

如果使用JAXB生成类,当然可以使用@XmlElements之类的不同类型来解析列表

现在,如果您也在Jersey/Jackson中使用相同的JAXB类,那么可以通过添加@JsonTypeInfo和@JsonSubTypes来增强类的元数据,以描述如何格式化对象列表/数组的名称

@JsonTypeInfo描述了要添加的类型,@JsonSubTypes提供了封闭集合的选项。例如,As.PROPERTY定义输出的一个属性,如下例所示,其中一个实体列表可以包含不同类型的元素,包括类型本身(“表单”)以及其他两种类型的“字段”和“表格”


我还没有足够的答案,但是。实体方法接受一个对象。底层代码可能在运行时检查类型以恢复类型信息。不幸的是,这将得到它的列表,而不是列表。它将其写为一个没有泛型类型信息的列表,因此您将丢失类字段。编写一个将列表作为成员变量的对象可能会起作用,但我正在尝试更简洁的方法。这是一个简单的解决方案,效果非常好,感谢您的分享!唯一的缺点是,我们必须记住始终以这种方式包装我们的收藏。
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;
     "entities": [
                  {
                    "obj": "Table",
                    "row": {
                        "id": 1,
                        "fields": [
                            {
                                "id": "DEBUGARY",
                                "type": "Text",
                                "kind": "user"
                            }
                        ]
                    },
                    "id": "DBGARRAY"
                },
                {
                    "obj": "field",
                    "id": "IDBG",
                    "type": "Text",
                    "kind": "user"
                },
        ..., ..., ...]