简体   繁体   English

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

[英]Polymorphic JSON deserialization (Jackson) of entity parameters (Google Cloud Endpoints)

I have a Cloud Endpoints API method which takes an entity parameter (ie JSON request body mapping to a POJO). 我有一个Cloud Endpoints API方法,该方法带有一个实体参数 (即JSON请求主体映射到POJO)。 This object contains a field who's type is an abstract class, ie: 该对象包含一个类型为抽象类的字段,即:

public class APIRequest {
  public String customerName;

  public BaseFilter filter;
}

The aforementioned API method has the following signature: 前面提到的API方法具有以下签名:

public SomeResponsePOJO doTheThing(User user, APIRequest requestEntity)

Now, according to Jackson's documentation , it should be possible to annotate the abstract class in such a way that, when deserialising, an instance of the appropriate concrete class is created, controlled by an additional type parameter on the request. 现在,根据Jackson的文档 ,应该可以对抽象类进行注释,以便在反序列化时,创建适当的具体类的实例,并由请求上的附加类型参数控制。

As per the documentation, I've annotated the abstract class as follows: 根据文档,我对抽象类进行了如下注释:

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

Where PeriodFilter is a concrete subclass of BaseFilter: 其中PeriodFilter是BaseFilter的具体子类:

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

  ...
}

A request is then made with the following body: 然后使用以下正文进行请求:

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

Unfortunately, GAE responds with the following error: 不幸的是,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\"])

As far as I can tell from the documentation, I've done everything required for this to work. 据我从文档中得知,我已经完成了所有必要的工作。 Unless I'm missing something, the error above would suggest that AppEngine is ignoring the Jackson annotations. 除非我缺少任何内容,否则上面的错误将表明AppEngine将忽略Jackson批注。

Have I missed something, or is what I'm trying to do simply not supported with Cloud Endpoints? 我是否错过了某些东西,或者我想做的事根本不支持Cloud Endpoints?

Thanks to @BrendanMolloy for pointing out the related question regarding GAE ignoring Jackson's annotations. 感谢@BrendanMolloy指出了有关GAE忽略Jackson注释的相关问题。 I had overlooked that Google repackages Jackson, hence it was looking for its own instances of the annotations, not those from Jackson proper. 我忽略了Google重新打包Jackson的方法,因此它正在寻找自己的注释实例,而不是Jackson的实例。

Importing the annotations from the repackaged version of Jackson works as expected, but is obviously less than ideal -prone to break without notice if Google changes things on their end. 从杰克逊的重新打包版本中导入注释可以按预期方式进行,但显然不理想-如果Google更改了内容,则很容易在没有通知的情况下中断。

It would seem that using @ApiTransformer and Jackson's ObjectMapper in the Transformer implementation would be the best approach, as much as it would have been preferable to simply use @JsonTypeInfo directly. 似乎在Transformer实现中使用@ApiTransformer和Jackson的ObjectMapper将是最好的方法,因为直接使用@JsonTypeInfo会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM