【问题标题】:"Abstract classes must be annotated with JsonTypeInfo" compiling DTO structure“抽象类必须用 JsonTypeInfo 注释”编译 DTO 结构
【发布时间】:2015-02-20 21:54:17
【问题描述】:

我有一个非常简单的 DTO 结构,它由一个接口、一个实现它的抽象类和抽象类下的类层次结构组成。 界面:

public interface InterfaceDTO {}

抽象类:

import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonSubTypes.Type;
import org.codehaus.jackson.annotate.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "json_type")
@JsonSubTypes({
    @Type(value = DataDTO.class, name = "DataDTO"),
    @Type(value = VectorDTO.class, name = "VectorDTO") })
public abstract class AbstractDTO implements InterfaceDTO {}

一级课程:

public class DataDTO extends AbstractDTO {
  private Short answerId;
  private String clientKey;
  private String answerText;
  .....

public class VectorDTO extends AbstractDTO {
  private Vector<InterfaceDTO> answers;

  public VectorDTO() {
    answers = new Vector<InterfaceDTO>();
  }

二级班:

public class DataWithReplyDTO extends DataDTO {
  private String replyData;

最后,restygwt JSON enc/dec 代码:

public interface InterfaceDTOCodec extends JsonEncoderDecoder<InterfaceDTO> {}
...
InterfaceDTOCodec codec = GWT.create(InterfaceDTOCodec.class);      
VectorDTO dto = new VectorDTO();
JSONValue json = codec.encode(dto);
InterfaceDTO other = codec.decode(json);
...

当我使用 GWT 2.6.1 和 restygwt 从 eclipse 编译时,我得到:

Compiling module com.test.web.MyApp
  Computing all possible rebind results for 'com.test.web.client.activity.InitActivity.InterfaceDTOCodec'
    Rebinding com.test.web.client.activity.InitActivity.InterfaceDTOCode
      Invoking generator org.fusesource.restygwt.rebind.JsonEncoderDecoderGenerator
        Generating: com.test.web.client.activity.InitActivity_InterfaceDTOCodec_Generated_ExtendedJsonEncoderDecoder_
          checking: org.fusesource.restygwt.client.JsonEncoderDecoder, type: class com.google.gwt.dev.javac.typemodel.JParameterizedType
          Generating: com.test.web.shared.dto.InterfaceDTO_Generated_JsonEncoderDecoder_
            [ERROR] Abstract classes must be annotated with JsonTypeInfo
  [ERROR] Errors in 'com/test/web/client/activity/InitActivity.java'
    [ERROR] Line 55: Failed to resolve 'com.test.web.client.activity.InitActivity.InterfaceDTOCodec' via deferred binding
  [WARN] For the following type(s), generated source was never committed (did you forget to call commit()?)
    [WARN] com.test.web.client.activity.InitActivity_InterfaceDTOCodec_Generated_ExtendedJsonEncoderDecoder_
    [WARN] com.test.web.shared.dto.InterfaceDTO_Generated_JsonEncoderDecoder_

按照指南,我向抽象类添加了注释,但仍然出现奇怪的错误消息。有什么帮助吗?

参考资料: http://resty-gwt.github.io/documentation/restygwt-user-guide.html RestyGWT Polymorphic Encode/Decode issues when using an interface instead of an abstract class

【问题讨论】:

    标签: resty-gwt


    【解决方案1】:

    我以经典的反复试验结束,并忽略了来自 restygwt 的文档。以下是我为使其工作所做的工作:

    1. 删除了抽象类并将注释移至接口。这个行为在official doc中不是很清楚:“其他类继承的超类必须是抽象类,并且像下面的例子那样注释”
    2. 当然改变类来实现接口而不是扩展抽象类
    3. @Type(value = DataWithReplyDTO.class, name = "DataWithReplyDTO"),添加到接口@JsonSubTypes列表中

    我在单元测试中使用了以下编码器/解码器声明并且它有效:

    public interface InterfaceDTOEncoderDecoder extends JsonEncoderDecoder<InterfaceDTO> {}
    

    底线:看起来你可以在一个接口下有多个继承级别,只要你将接口中的所有类型声明为@JsonSubTypes,它仍然可以工作

    【讨论】:

      【解决方案2】:

      尝试删除 DataWithReplyDTO 看看是否有效。

      我猜你不能有 2 个级别的非抽象类。代码如何知道它是否需要创建 DataWithReplyDTO 或 DataDTO ?

      【讨论】:

      • 我找到了解决方案。是的,您可以在抽象类下拥有 +1 级别。事实上,我删除了它。看我的回答
      • 我的观点是关于未在 JsonSubtype 中声明的 DataWithReplyDTO,我看到您在答案中添加了它
      猜你喜欢
      • 2014-05-03
      • 2021-06-11
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      相关资源
      最近更新 更多