2012-05-04 59 views
5

我正在开发一个泽西岛的应用程序,我有很多资源。虽然这些资源的主要功能各不相同,但它们共享许多常用方法(如列表,读取,更新等)。该应用在Google App Engine上运行,并使用Guice进行依赖注入。使用继承和泛型组织Jersey资源的正确方法是什么?

我的第一种方法是拥有一个通用的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 
} 

正如您所见,此例中的类型参数已更改(现在它扩展了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 

我真的不知道这种方法是否正确使用泽西岛,如果我可以忽略这个消息。知道如何组织大量资源的情况是很有趣的。

回答

4

一种方法是从实施中分离资源的定义。

  • 拥有非常简单的资源类,定义您想要提供的不同服务。通过这种方式,您通过其他方式公开的API可以轻松定位和审核。不同的方法可能代表实现类
  • 在实现中实现资源的业务逻辑,您可能希望使用继承来分析常见行为。

在运行时得到这些消息的原因是球衣使用有关资源中类型的运行时信息。泛型类型信息在编译时被擦除,它不能获得泛型类方法的实际返回类型。如果你为你的实现提供了一个REST“门面”,你可以明确地说明这一点。

public class Facade { 
    private final PropertyResource propertyResource; 
    public Facade() { 
    propertyResource = new PropertyResource(); 
    } 
    @GET 
    @Path("somepath") 
    public Tenant something() { 
    return propertyResource.something(); 
    } 
} 
+0

非常感谢您的建议。现在我明白了我的方法所遇到的问题。我会尝试按照您的建议分离定义和实施 – turan