Olá, estou trabalhando em um sistema onde a busca é um dos principais quesitos e então, agora, decimos mostrar para o usuario, como o google faz, quanto tempo uma determinada consulta levou para ser executada. Então implementei um interceptor assim:
O problema é que o codigo após o invocation.invoke() é executado apenas depois que a JSP é completamente renderizada e colocar o valor do tempo no contexto da action não vai adiantar porque a JSP já foi completamente mostrada quando ele ficar disponivel no contexto.
Eu tentei colocar o tempo na session, mas passei a recuperar o tempo da requisição anterior, não da atual. Eu sei que servlet filters têm o mesmo comportamento, então, como vcs sugerem que eu implemente essa medida de tempo de maneira elegante?
Nunca precisei usar, mas não custa nada dar uma olhadinha no source dele para ver como o danado faz :thumbup:
smota
Ops … perai!
O interceptor é sim processado antes do result, tanto é que você pode fazer interceptors para alterar o result retornado (por exemplo se o caboclo não estiver logado).
Acho que o jeito mais fácil ao invés de usar o contexto (que não tem muito a ver com as expressões usadas na view) seja usar a própria action ou colocar um outro objeto na pilha.
Usando a própria action crie uma interface public interface TimedAction { public void setExecutionTime(long time) }, crie uma super-classe para todas as actions que você queira cronometrar a execução, ou implemente a interface diretamente na classe em questão e mude seu interceptor pra algo comAction action = invocation.getAction();
...
if(action instanceof TimedAction)
(TimedAction) action).setExecutionTime(watch.getTotalTimeSeconds()) e finalmente coloque um getExecutionTime() na action que quiser e use na view $executionTime (velocity)
jack_ganzha
Olá,
LIPE, o problema é que o TimerInterceptor apenas loga o tempo necessario, ele não deixa o valor disponivel para acessar a partir de uma view, por exemplo, que é justamente o que eu quero. Tanto que esse interceptor é usado geralmente apenas durante o desenvolvimento.
valeuz…
jack_ganzha
Samuel, parte do interceptor é executada antes da renderização ser feita e outra parte é executada *depois*. O codigo que fica após o invocation.invoke só é processado depois que a view é completamente mostrada. Fiz o seguinte teste: coloquei um System.out.println("HELLO!!!") no fim da minha jsp e o log gerado foi:
Ou seja, não vai adiantar setar o tempo na action depois de mostrar a JSP porque meu intuito é mostrar o tempo *na jsp*.
valeuz...
_fs
Pera, você esta colocando esse código na JSP, mas queria que ele fosse executado antes de mandar para a JSP??
jack_ganzha
No minha JSP eu tenho apenas o seguinte:
<ww:propertyvalue="time"/>
“time” eu gostaria de setar no interceptor que registra o tempo de execução da Action, mas preciso executar a action antes para poder registrar o tempo (Oohh!), só que a parte do interceptor que coloca o valor no contexto da action só executa depois que a JSP é completamente renderizada, então, o valor de time está vazio.
Eu tentei o que o Samuel sugeriu, mas sem sucesso.
valeuz…
smota
Fio, vou ficar te devendo uma explicação ultra-mega-maluca do porque essa parada acontece com seu teste, mas eu ([size=9]quase[/size]) garanto que todos os interceptors são executados antes dos results, essa é a idéia deles, interceptar a ação e agir sobre ela alterando o resultado [SGM05]
Lembrando que existem AroundInterceptors e outras coisitas diferentes do simples Interceptor.
Que tem jeito de fazer usando o interceptor sem gambiarra (acho) tem, to sem um ambiente pra testar aqui … mas faça uma versão simples do seu e manda pra cá que nóis tenta de novo.
ehehe foi mal ficar saindo de fininho com os achos e quase mas faz um tempinho que nao faço nada interessante com o Webwork e posso estar meio perdido
Só acho que meu exemplo foi mais elegante do que colocar na session :mrgreen:
jack_ganzha
Samuel, veja ele coloca o greeting no contexto, *antes* disso:
String result = invocation.invoke();
No meu caso, como eu preciso registrar o tempo de execução da action incluindo os outros interceptors, eu preciso colocar o valor *depois* de chamar o invoke:
publicStringintercept(ActionInvocationinvocation)throwsException{Stringname=getActionName(invocation);StopWatchwatch=newStopWatch();watch.start(name);ActionContextcontext=ActionContext.getContext();Stringresult=invocation.invoke();// daqui para frente é executado depois que a JSP foi mostrada!// Serio... :-pwatch.stop();context.put("time",newDouble(watch.getTotalTimeSeconds()));returnresult;}
Esse interceptor está no topo da stack para poder registrar *todo* o tempo.