6

我正在用 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
}

如您所见,本例中的类型参数已更改(现在它扩展了 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 是否正确,我是否可以忽略这些消息。如果资源数量众多,那么了解资源的组织方式会很有趣。

4

1 回答 1

4

一种方法是将资源的定义与实现分开。

  • 拥有非常简单的资源类,定义您想要提供的不同服务。这样,您通过 rest 公开的 API 很容易定位和审计。不同的方法可能是实现类的委托
  • 在实现中实现资源的业务逻辑,您可能希望在其中使用继承来考虑常见行为。

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

public class Facade {
  private final PropertyResource propertyResource;
  public Facade() {
    propertyResource = new PropertyResource();
  }
  @GET
  @Path("somepath")
  public Tenant something() {
    return propertyResource.something();
  }
}
于 2012-05-04T21:18:25.133 回答