Caching 在ServerResource发送的表示上设置ETAG/LastModified
我知道我可以在Representation/Repre上设置ETAG和LastModified属性句子信息。 但我有一个简单的资源实现如下:Caching 在ServerResource发送的表示上设置ETAG/LastModified,caching,restlet,etag,Caching,Restlet,Etag,我知道我可以在Representation/Repre上设置ETAG和LastModified属性句子信息。 但我有一个简单的资源实现如下: public class AccountServerResource extends ServerResource implements AccountResource { private static Logger log = Logger.getLogger(AccountServerResource.class.getName());
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;
}
}
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));
}
}
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/LastModified标记
这里的推荐做法是什么
---更新---
我尝试了这种方法,但运气不好:
@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;
}
@覆盖
公共帐户检索(){
User User=getClientInfo().getUser();
AccountDAO=新的AccountDAO(user.getNamespace());
AccountDAO=新AccountDAO();
Account ret=dao.getAccountByEmail(user.getEm)ail());
日志信息(“已检索”+ret);
设置事件(新的StrongEtagCallback(ret));
返回ret;
}
StrongEtagCallback的实现如下:
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;
}
}
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));
}
}
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;
}
公共类StrongEtagCallback实现统一{
私有静态SimpleDataFormat df=新SimpleDataFormat(“ddMMYYYYHMMSSSS”);
私有域资源d;
公共StrongEtagCallback(T域资源){
d=域资源;
}
@凌驾
公共无效句柄(请求、响应){
字符串eTag=d.getClass().getSimpleName()+“-”+d.getId()+“-”+df.format(d.getLastModified());
response.getEntity().setTag(新标记(eTag,false));
}
}
我的所有实体都实现DomainResource,这要求它们具有ID和LastModified日期
但它不起作用。我真的很期待这个工作,它是非常优雅的强>
不过,正在调用StrongEtagCallback,即实体上的ETAG集合服务器端。我的Wireshark或GWT客户端在响应的响应上看到一个E-TAG头。现在深入研究。最终的解决方案是将返回域实体设为局部变量,并重写ServerResource的handle()方法。这是安全的,因为javadoc声明: 为处理的每个调用创建一个ServerResource实例,并 一次只能由一个线程访问 因此,实现如下所示:
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;
}
}
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));
}
}
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;
}
PS:我的第一个设置回调
setOnSent
的解决方案是在提交响应后执行的,这就是为什么这个解决方案不起作用。实际上,我希望有一个类似的钩子或某种setNext()
Restlet来做后期处理。毕竟,回调实现了Uniform
接口。在我看来,这将更适合Restlet的整体架构。在我自己研究这个问题时,我注意到了一个由koma在Restlet讨论板上发起的项目,其中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;
}