实体参数的多态JSON反序列化(Jackson)(Google Cloud Endpoints)

时间:2016-01-20 05:56:49

标签: java json google-app-engine jackson google-cloud-endpoints

我有一个Cloud Endpoints API方法,它采用entity parameter(即JSON请求主体映射到POJO)。该对象包含一个字段,其类型是抽象类,即:

public class APIRequest {
  public String customerName;

  public BaseFilter filter;
}

上述API方法具有以下特征:

public SomeResponsePOJO doTheThing(User user, APIRequest requestEntity)

现在,根据Jackson的documentation,应该有可能以这样一种方式注释抽象类:当反序列化时,创建一个适当的具体类的实例,由一个附加的类型参数控制。请求。

根据文档,我按如下方式对抽象类进行了注释:

@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="filterType")
@JsonSubTypes({
  @Type(value = PeriodFilter.class, name = "Period")
})
public abstract class BaseFilter {
  ...
}

其中PeriodFilter是BaseFilter的具体子类:

public class PeriodFilter extends BaseFilter {
  private Date startDate;
  private Date endDate;

  ...
}

然后使用以下正文发出请求:

{
  "customerName": "Derp Pty Ltd",
  "filter": {
    "filterType": "Period",
    "startDate": "2016-01-01",
    "endDate": "2016-01-31"
  }
}

不幸的是,GAE回应了以下错误:

com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException:
  Can not construct instance of <package name>.BaseFilter, problem:
    abstract types can only be instantiated with additional type information
    at [Source: N/A; line: -1, column: -1]
    (through reference chain: <package name>.APIRequest[\"filter\"])

据我从文档中可以看出,我已经完成了所需的一切工作。除非我遗漏了某些内容,否则上述错误表明AppEngine忽略了杰克逊的注释。

我是否遗漏了某些内容,或者我正在尝试做什么,根本不支持Cloud Endpoints?

1 个答案:

答案 0 :(得分:0)

感谢@BrendanMolloy指出有关GAE忽略杰克逊注释的相关问题。我忽略了谷歌重新包装杰克逊,因此它正在寻找自己的注释实例,而不是杰克逊本身的实例。

从杰克逊的重新打包版本导入注释按预期工作,但显然不太理想 - 如果谷歌改变了结果,那么在没有通知的情况下破解。

在Transformer实现中使用@ApiTransformer和Jackson的ObjectMapper似乎是最好的方法,就像直接使用@JsonTypeInfo更好。