2012-01-26 18 views
1

我知道我可以在Representation/RepresentationInfo上設置ETAG和LastModified屬性。 但我有一個像這樣實現了一個簡單的資源:在ServerResource發送的表示形式上設置ETAG/LastModified

public class AccountServerResource extends ServerResource implements AccountResource { 

    private static Logger log = Logger.getLogger(Acc​ountServerResource.c​lass.getName()); 

    @Override 
    public Account retrieve() { 
     User user = getClientInfo().getUser(); 
     AccountDAO dao = new AccountDAO(); 
     Account ret = dao.getAccountByEmai​l(user.getEm​ail()); 
     log.info("retrieved " + ret); 
     // getResponse().getEntity() == null at this point !!! 
     // ---> cannot do this : getResponse().getEntity().setModificationDate(ret.getLastMod​ified()); 
     return ret; 
    } 
} 

的表示還沒有連接到此時的響應。 何時/如何設置ETAG/LastModified標籤?

這裏推薦的做法是什麼?

--- UPDATE ---

我試過沒有運氣這種方法:

@Override 
public Account retrieve() { 
     User user = getClientInfo().getUser(); 
    AccountDAO dao = new AccountDAO(user.getN​amespace()); 
     AccountDAO dao = new AccountDAO(); 
     Account ret = dao.getAccountByEmai​l(user.getEm​ail()); 
    log.info("retrieved " + ret); 
    setOnSent(new StrongEtagCallback​<Account>(ret));​ 
    return ret; 
} 

和實施StrongEtagCallback的是這樣的:

public class StrongEtagCallback<T extends DomainResource> implements Uniform { 

    private static SimpleDateFormat df = new SimpleDateFormat("dd​MMyyyyHHmmssSSS"); 
    private DomainResource d; 

    public StrongEtagCallback(T domainResource) { 
     d = domainResource; 
    } 

    @Override 
    public void handle(Request request, Response response) { 
     String eTag = d.getClass().getSimpleName() + "-" + d.getId() + "-" + df.format(d.getLastModified()); 
     response.getEntity().setTag(new Tag(eTag, false)); 
    } 
} 

凡我所有實體實施要求他們具有ID和LastModified日期的DomainResource。

但它不起作用。我真的期待這個工作,它非常優雅!

雖然正在調用StrongEtagCallback,但ETAG在實體上設置了服務器端。我的Wireshark或我的GWT客戶端都會在響應的響應中看到一個E-TAG標頭。現在深入潛水。

回答

2

在自己研究這個問題時,我注意到在Restlet討論板上由koma開始的一個parallel thread,其中替代和可取的解決方案由Tim Peierls提供,即覆蓋Resource.toRepresentation()。

正如koma在該主題中指出的,覆蓋ServerResource.handle()導致條件匹配失敗(我不知道爲什麼?),所以這種方法是有問題的。蒂姆·佩爾斯提供

示例性的失控代碼:

@Override public Representation toRepresentation(Object source, Variant target) { 
    Representation rep = super.toRepresentation(source, target); 
    if (source instanceof HasLastModified) { 
     HasLastModified hlm = (HasLastModified) source; 
     rep.setModificationDate(hlm.getLastModified()); 
    } 
    if (source instanceof HasEtag) { 
     HasEtag he = (HasEtag) source; 
     rep.setTag(he.gettag()); 
    } 
    return rep; 
} 
+0

是的,你說得對,我的答案是過時的。 – koma

1

最終的解決方案是使返回域實體成爲局部變量並覆蓋ServerResource的handle()方法。這是安全的,因爲javadoc中指出:

一個ServerResource的實例爲處理的每個呼叫和 只有一個線程在同一時間訪問創建

所以執行是這樣的:

private Account ret = null; 

@Override 
public Account retrieve() { 
    User user = getClientInfo().getUser(); 
    AccountDAO dao = new AccountDAO(); 
    ret = dao.getAccountByEmail(UserServiceFactory.getUserService().getCurrentUser().getEmail()); 
    // getResponse().getEntity().setModificationDate(ret.getLastModified()); 
    // lastModified = ret.getLastModified(); 
    log.info("retrieved " + ret); 
    //setOnSent(new StrongEtagCallback<Account>(ret)); 
    return ret; 
} 

@Override 
public Representation handle() { 
    Representation representation = super.handle(); 
    if (ret != null) { 
     new StrongEtagCallback<Account>(ret).handle(getRequest(), getResponse()); 
    } 
    return representation; 
} 

的ETAG頭現在發送:

HTTP/1.1 200 OK 
Content-Type: application/x-java-serialized-object+gwt; charset=UTF-8 
ETag: "Account-104-27012012003721199" 
Date: Thu, 26 Jan 2012 23:44:32 GMT 
Accept-Ranges: bytes 
Server: Restlet-Framework/2.1rc1 
Transfer-Encoding: chunked 

PS:我的第一個解決方案設置回調setOnSent在響應提交後執行,這就是爲什麼此解決方案不起作用。我實際上會期望類似的鉤子或某種類型的Restlet進行後期處理。畢竟,回調實現了Uniform接口。海事組織,這將更適合Restlet的整體架構。