我知道我可以在Representation / Repre sentationInfo上设置ETAG和LastModified属性。 但我有一个像这样实现的简单资源:
public class AccountServerResource extends ServerResource implements AccountResource {
private static Logger log = Logger.getLogger(AccountServerResource.class.getName());
@Override
public Account retrieve() {
User user = getClientInfo().getUser();
AccountDAO dao = new AccountDAO();
Account ret = dao.getAccountByEmail(user.getEmail());
log.info("retrieved " + ret);
// getResponse().getEntity() == null at this point !!!
// ---> cannot do this : getResponse().getEntity().setModificationDate(ret.getLastModified());
return ret;
}
}
此时此表示尚未附加到回复中。 何时/如何设置ETAG / LastModified标签?
这里的推荐做法是什么?
--- --- UPDATE
我没有运气就试过这种方法:
@Override
public Account retrieve() {
User user = getClientInfo().getUser();
AccountDAO dao = new AccountDAO(user.getNamespace());
AccountDAO dao = new AccountDAO();
Account ret = dao.getAccountByEmail(user.getEmail());
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("ddMMyyyyHHmmssSSS");
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));
}
}
我的所有实体都实现了DomainResource,要求它们拥有ID和LastModified日期。
但它不起作用。我真的希望这个有用,非常优雅!
正在调用StrongEtagCallback,ETAG在实体上设置服务器端。我的Wireshark和我的GWT客户端在响应的响应中看到了E-TAG标头。现在潜水更深。
答案 0 :(得分:2)
在我自己研究这个问题时,我注意到在Restlet讨论板上由koma发起的parallel thread,其中Tim Peierls提供了另一种更好的解决方案,即覆盖Resource.toRepresentation()。
正如koma在该线程中指出的那样,覆盖ServerResource.handle()
导致条件匹配失败(我不确定为什么?),因此这种方法存在问题。
Tim Peierls提供的覆盖代码示例:
@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;
}
答案 1 :(得分: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
的解决方案在响应提交后被激活,这就是为什么这个解决方案不起作用的原因。我实际上期望一个类似的钩子或某种有点setNext()
Restlet来进行后处理。毕竟,回调实现了Uniform
接口。 IMO,这将更适合Restlet的整体架构。