2012-05-04 60 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