我正在开发一个应用Jersey的应用程序,我有很多资源。虽然这些资源的主要功能各不相同,但它们共享许多常用方法(如列表,读取,更新等)。该应用程序在Google App Engine上运行,并使用Guice进行依赖注入。
我的第一个方法是拥有一个包含所有通用逻辑的通用AbstactResource,它分别由添加所需自定义方法的所有其他资源进行扩展。
public class AbstractResource<T> {
@GET
public ListPage<T> list(@QueryParam("limit") Integer limit,
@QueryParam("start") Integer start) {
// ... implementation
}
@GET
@Path("/{id}")
public T get(@PathParam("id") Long id) {
// ... implementation
}
示例资源如下:
public class TenantResource extends AbstractResource<Tenant> {
// custom resource related methods here
}
在这种情况下一切正常。当我添加一个更多抽象级别时会出现问题。假设我只想为某些资源存储历史记录和更改日志。我创建了另一个扩展AbstractResource的抽象类,名为AudiatableResource,它添加了所需的功能。
public abstract class AuditableResource<T extends AuditableModel>
extends AbstractResource {
// here I override update and create methods to save changelogs
}
如您所见,此案例中的type参数已更改(现在它扩展了AuditableModel)。
新的具体资源如下:
public class PropertyResource extends AuditableResource<Tenant> {
// custom resource related methods here
}
在这种情况下,一切仍然有效,但这次我在启动时收到很多警告信息:
WARNING: Return type T of method public T com.pkg.AbstractResource.get(java.lang.Long) is not resolvable to a concrete type
WARNING: Return type T of method public T com.pkg.AbstractResource.getNew() is not resolvable to a concrete type
WARNING: Return type com.pkg.data.ListPage<T> of method public com.pkg.ListPage<T> com.pkg.AbstractResource.list(java.lang.Integer,java.lang.Integer) is not resolvable to a concrete type
我真的很想知道这种方法使用Jersey是否正确,如果我可以忽略这些消息。知道如何在有大量资源的情况下组织资源会很有趣。
答案 0 :(得分:4)
一种方法是将资源的定义与实现分开。
在运行时获取这些消息的原因是jersey使用有关资源中类型的运行时信息。通用类型信息在编译时被擦除,它无法获得泛型类方法的实际返回类型。如果为实现提供REST“外观”,则可以明确说明。
public class Facade {
private final PropertyResource propertyResource;
public Facade() {
propertyResource = new PropertyResource();
}
@GET
@Path("somepath")
public Tenant something() {
return propertyResource.something();
}
}