Установка ETAG / LastModified для представления, отправленного ServerResource - PullRequest
1 голос
/ 26 января 2012

Я знаю, что могу установить свойства ETAG и LastModified для Представления / ПредставленияInfo. Но у меня есть простой ресурс, реализованный так:

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));
    }
}

Где все мои сущности реализуют DomainResource, который требует, чтобы у них были идентификатор и дата последнего изменения.

Но это НЕ работает. Я действительно ожидал, что это сработает, это очень элегантно!

Хотя вызывается StrongEtagCallback, ETAG устанавливает серверную часть на объекте. Мой Wireshark и мой клиент GWT не видят заголовок E-TAG в ответе на ответ. Погружаемся глубже.

Ответы [ 2 ]

2 голосов
/ 26 февраля 2012

При самостоятельном исследовании этой проблемы я заметил параллельный поток , запущенный koma на доске обсуждений Restlet, в котором Тим Пайерлс предложил альтернативное и предпочтительное решение, а именно переопределение 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;
}
1 голос
/ 27 января 2012

Окончательным решением было сделать сущность возвращаемого домена локальной переменной и переопределить метод handle () ServerResource.Это безопасно, потому что 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.ИМО, это будет лучше вписываться в общую архитектуру Рестлета.

...