2014-12-22 4 views
0

У меня довольно простая структура DTO, состоящая из интерфейса, абстрактного класса, реализующего его, и иерархии классов под абстрактным классом. Интерфейс:«Абстрактные классы должны быть аннотированы с помощью JsonTypeInfo», компилируя структуру 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 J SON ENC/Декабрь код:

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 я получаю:

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

ответ

0

Я закончил с классическим испытанием и ошибкой и видом игнорирования документов из restygwt. Вот что я сделал для того, чтобы это заработало:

  1. Удален абстрактный класс и перенесены аннотации в интерфейс. В official doc это поведение не очень ясно: «Суперкласс, который наследуют другие классы, должен быть абстрактным классом и аннотирован как пример ниже»
  2. Конечно, измененные классы для реализации интерфейса вместо расширения абстрактного класса
  3. Добавлена ​​@Type(value = DataWithReplyDTO.class, name = "DataWithReplyDTO"), к интерфейсу @JsonSubTypes список

Я использовал следующий кодер/декодер заявление в моем тестовом модуле, и она работала:

public interface InterfaceDTOEncoderDecoder extends JsonEncoderDecoder<InterfaceDTO> {} 

Нижняя строка: кажется, что вы можете иметь несколько уровней наследования под интерфейсом, и он по-прежнему работает до тех пор, пока вы объявляете все типы интерфейса как @JsonSubTypes

0

Попробуйте удалить DataWithReplyDTO и посмотреть, если он работает.

Я предполагаю, что у вас не может быть 2 уровня не-абстрактных классов. Как код мог знать, нужно ли создавать DataWithReplyDTO или DataDTO?

+0

Я нашел решение. Да, вы можете иметь +1 уровень под абстрактным классом. Фактически я удалил его. См. Мой ответ – Taka

+0

Моя точка зрения была о DataWithReplyDTO, не объявленной в JsonSubtype, я вижу, что вы добавили ее в свой ответ –