支持Polymorphism和Generics的运输层

时间:2015-12-01 14:53:28

标签: ajax generics gwt polymorphism

我正在寻找gwt的运输层。我想使用泛型方法创建ajax请求,这是我的DAO /服务:

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 /实体:

@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我的所有实体下载,所以我应该只有一个客户端的通用方法)。

我已经查过:

  • GWT-RPC
  • RequestFactory
  • RestyGWT

但他们都不支持此功能。

我在这里找到了:

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

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

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

为了更好地理解,请同时查看: RequestFactory client-side inheritance of typed class with generics

1 个答案:

答案 0 :(得分:0)

我很困惑为什么你认为RPC无法处理泛型 - 根据你的链接,可以,但RestyGWT不能。当然,您的JPA引用都没有在GWT中有任何意义,但是它们将存在于服务器上的DAO中,而不是实体/模型类本身,或者至少不存在于客户端版本中。如果您的RPC方法返回 #mainPage { width: 100%; height: 100%; font-size: 3vw; text-transform: uppercase; background: black; font-weight: bold; position: fixed; background-image: url('imagesfolder/someImage.jpg'); } T,那么您将拥有每个可能的<T extends GenericModel<T>>子类型的序列化器,并且任何/所有gwt兼容的方法都可以通过线路发送

从更新编辑到问题:

您的GenericModel<?>类使用在GWT中无法使用的Java功能,例如反射。这不能编译为GWT,因为编译器依赖于删除反射信息以最小化编译大小 - 一般而言,反射信息意味着留下所有类和成员的详细信息,甚至是那些无法静态证明正在使用的类和成员,因为一些反思可能会利用它们。

如果有办法以一种只处理手头数据的方式对模型对象进行短语,请关注它。否则考虑一个DTO,它只是通过网络发送的数据 - 我不确定你打算如何使用客户端上的GenericModel字段,或者为什么从超类的泛型中读取这些信息很重要仅使用entityClass

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