支持多态和泛型的传输层

Transportation layer that support Polymorphism and Generics

我正在寻找 gwt 的传输层。我想使用通用方法创建 ajax 请求,f.e 这是我的 DAO/service:

public class GenericDao<T extends GenericModel<T>> {
    private Logger logger = LoggerFactory.getLogger(this.getClass().getCanonicalName());
    @Transient protected Class<T> entityClass;


    public GenericDao() {
        super();
    }
    public GenericDao(Class<? extends GenericModel<T>> clazz) {
        this.entityClass = (Class<T>) clazz;
    }

    public T getBy(Long id) {
        return JPA.em().find(entityClass, id);
    }
    public List<GenericModel<T>> get() {
        logger.error("trying to get data from db");
        return getList();
    }
    public List<GenericModel<T>> getList() {
        return JPA.em().createQuery("FROM " + entityClass.getSimpleName()).getResultList();
    }
    public void save(GenericModel<T> entityClass) {
        JPA.em().getTransaction().begin();
        JPA.em().persist(entityClass);
        JPA.em().getTransaction().commit();     
    }
    public void update(T entityClass) {
        JPA.em().getTransaction().begin();
        JPA.em().merge(entityClass);
        JPA.em().getTransaction().commit();
    }

    public void delete(T entityClass) {
        JPA.em().getTransaction().begin();
        JPA.em().remove(entityClass);
        JPA.em().getTransaction().commit();
    }
}

GenericModel/Entity:

@MappedSuperclass
public  class GenericModel<T extends GenericModel<T>> implements Identifiable, Versionable {
    @Transient
    protected Class<T> entityClass;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Version
    private Integer version;

    // setter & getter
    @Override
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    @Override
    public Integer getVersion() {return version;}
    public void setVersion(Integer version) {this.version = version;}

    // constructor
    public GenericModel() {
        Class<?> obtainedClass = getClass();
        Type genericSuperclass = null;
        for (;;) {
            genericSuperclass = obtainedClass.getGenericSuperclass();
            if (genericSuperclass instanceof ParameterizedType) {
                break;
            }
            obtainedClass = obtainedClass.getSuperclass();
        }
        ParameterizedType genericSuperclass_ = (ParameterizedType) genericSuperclass;
        try {
            entityClass = ((Class) ((Class) genericSuperclass_
                    .getActualTypeArguments()[0]));
        } catch (ClassCastException e) {
            entityClass = guessEntityClassFromTypeParametersClassTypedArgument();
        }
    }


    public GenericModel(Long id) {
        this();
        this.id = id;
    }
}

我正在寻找允许我在客户端的所有模型中使用此通用服务的机制(每个数据库实体都有 id- 所以我想以这种方式使用 ajax 我所有的实体进行下载,所以我应该在客户端只有一个通用方法。

我已经检查过:

但是其中 none 个支持此功能。

我在这里找到:

https://www.mail-archive.com/google-web-toolkit@googlegroups.com/msg100095.html

信息:gwt-jackson supports generics and polymorphism。不幸的是,我没有找到任何有效的例子。有人可以帮忙,举个例子,认可那个信息吗?

所有实体都有 id 和 version 参数。所以我想在客户端 RF 上有一个方法,它允许我通过 id 从服务器(service/dao/whatever)获取该实体 - 就像这样: Request getBy(Long id);但不幸的是我无法让它发挥作用。我喜欢射频方式,所以我先尝试了。通常我不会重复通过 id.entity/proxy 下载 entity/proxy 的代码。

为了更好地理解,请同时查看:

我对您认为 RPC 无法处理泛型的原因感到困惑 - 根据您的 link,它 可以 ,但 RestyGWT 不能。诚然,none 的 JPA 引用在 GWT 中是有意义的,但它们将存在于服务器上的 DAO 中,而不是 entity/model class 本身,或者至少不存在于客户端中版本。如果您有一个返回 T 的 RPC 方法,其中 <T extends GenericModel<T>>,那么您将拥有每个可能的 GenericModel<?> 子类型的序列化程序,并且可以发送与 gwt 兼容的 any/all电线。


从更新到问题的编辑:

您的 GenericModel class 使用了 Java 的功能,这些功能在 GWT 中无法使用,例如反射。这不能编译为 GWT,因为编译器依赖于删除反射信息来最小化编译后的大小——保留一般反射信息意味着保留所有 classes 和成员的详细信息,即使是那些它无法静态证明的信息正在使用中,因为某些反射可能会使用它们。

如果有一种方法可以用一种只处理手头数据的方式来表达您的模型对象,请专注于此。否则考虑一个 DTO,它只是通过网络发送的数据——我不确定你打算如何在客户端上使用 entityClass 字段,或者为什么从 superclass 的泛型而不是仅仅使用 getClass().

RequestFactory 将很难处理泛型 - 与 RPC(可能还有 RestyGWT)不同,它无法按照您想要的方式处理多态性,而是只会发送声明类型的字段,而不是任何任意子类型。如果客户端可以处理,RPC 将实际发送实例。