| Autor |
Mensagem |
|
|
Num posso.
Explicação melhor. Como eu poderia explicar melhor?
Para manter a sessão: ao fazer login o sistema faz um insert na base. Gera um UUID como chave, devolve o UUID para o usuário. Esse é mantido no cookie.
Quando o usuário desloga o registro é removido. O Registro tem um tempo de duração e uma data de última atividade... Essa data de atividade pode ser atualizada.
[]'s
Rodrigo
|
 |
|
|
Estou documentando uma solução de auditoria que desenvolvemos aqui com uma ajuda do Lucas.
No site do VRaptor existe um exemplo sobre como utilizar os interceptadores como Log.
O problema é que no mundo real não basta logar o que está sendo chamado. É preciso saber quem está fazendo a ação, verificar se essa pessoa tem permissão para realizar a ação requerida e registrar o que ela está fazendo (método e parâmetros). Para isso, criamos dois interceptadores, SecurityInterceptor e o AuditInterceptor.
A solução que aqui propomos permite o uso de balanceamento por Round Hobin entre servidores WEB ao manter a sessão centralizada numa base de dados.
Recuperamos do Cookies HTTP, no SecurityInterceptor, uma chave de segurança gerada no momento do login.
O registro da sessão é procurada na base local que mantém todas sessões ativas (a chave primária é o sessionId). Esse valor sessionId é mantido no cookie do navegador e sempre que uma requisição é feita a chave também é enviada.
Uma vez que a sessão é validada, os valores da sessão (que estavam na base) são guardados num objeto de requisição para serem usados nos passos seguintes a autorização (ex: auditoria e a execução em si do método). Para isso utilizamos um SessionWrapper.
Temos então que o AuditInterceptor deve ser executado após o SecurityInterceptor. Isso é feito com uso com a anotação @Intercepts(after = SecurityInterceptor.class).
Como precisamos saber quais os parâmetros são utilizados no log, colocamos o MethodInfo no constructor do AuditInterceptor. Abaixo, segue a snippet da implementação do Interceptor.
Existe uma oportunidade de melhoria nesse ponto. Os parâmetros chegam ao servidor inicialmente como String são convertidos para Objeto. Agora, nesse ponto convertemos novamente para String. Recuperando os valores originais da requisição teremos uma utilização mais racional de recursos.
Agora, nos deparamos com outro problema. Nossos Controllers guardam a sessão do usuário diretamente (uma vez que não faz sentido para eles guardarem o SessionController). No construtor desses controllers invocamos o método getSession do SesisonWrapper. Para garantir que o SessionWrapper terminou de ser carregado, Adicionamos a anotação o parâmetro (before=InstantiateInterceptor.class) em nossos interceptadores.
E ai está...
|
 |
|
|
A solução do drigo.angelo tá certa e é 100% segura uma vez que não será possível estender a classe Malha (porque o construtor é privado).
[]'s
Rodrigo
|
 |
|
|
Descobri o problema ...
A classe "proxificada" só tem os métodos raw.
Daí, falha a chamada
|
 |
|
|
Habilitei o Log do VRaptor, e anexei o log.
Parece que é justamente a lista de tags o problema.
11:37:16,426 DEBUG [OgnlParametersProvider] Applying tags[1] with [ calma ai]
30/03/2011 11:37:16 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [default] in context with path [/plataforma-de-videos] threw exception
br.com.caelum.vraptor.VRaptorException: Unable to find converter for java.util.List
|
 |
|
|
Em geral não é uma boa prática deixar a referência do objeto vazar no construtor.
publishing an object from within its constructor can publish an incompletely constructed object. This is true even if the publication is the last statement in the constructor. If the this reference escapes during construction, the object is considered not properly constructed.
Seria melhor fazer isso num Factory Method.
|
 |
|
|
Sorry, esqueci de colocar o corpo do post...
Aqui:
A entidade é a que segue:
Ou seja, o erro não ocorre apenas com rawtypes. O fork que você está trabalhando está no github?
|
 |
|
|
Né possível...
Lucas, parece que tem algum bug ainda...
Poderia dar uma olhada !?
29/03/2011 20:27:09 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [default] in context with path [/plataforma-de-videos] threw exception
br.com.caelum.vraptor.VRaptorException: Unable to find converter for java.util.List
at br.com.caelum.vraptor.core.DefaultConverters.to(DefaultConverters.java:59)
at br.com.caelum.vraptor.http.ognl.ListAccessor.setProperty(ListAccessor.java:86)
at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2225)
at ognl.ASTProperty.setValueBody(ASTProperty.java:127)
at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
at ognl.SimpleNode.setValue(SimpleNode.java:279)
at ognl.ASTChain.setValueBody(ASTChain.java:227)
at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
at ognl.SimpleNode.setValue(SimpleNode.java:279)
at ognl.Ognl.setValue(Ognl.java:737)
at ognl.Ognl.setValue(Ognl.java:783)
at br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.setProperty(OgnlParametersProvider.java:181)
at br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.createParameter(OgnlParametersProvider.java:149)
at br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.getParametersFor(OgnlParametersProvider.java:100)
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:107)
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:79)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:4
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at com.r7.videos.security.interceptor.SecurityInterceptor.intercept(SecurityInterceptor.java:72)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.guice.GuiceProvider.provideForRequest(GuiceProvider.java:81)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:550)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:11
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:380)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:18
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:28
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
|
 |
|
|
iiiiiiiiiiiiééééééééééééésssssssssss!!!!
Carai... Funcionou! Não acredito! Os cara aqui estão pulando de alegria!
Vlw Lucas.
|
 |
|
|
Acho que estou fazendo alguma coisa de errado.
Coloquei o tomcat em debug mode mas o meu DirtWatcherOgnlParametersProvider não é chamado.
Como eu registro o DirtWatcherOgnlParametersProvider? Precisa colocar alguma notação?
Vlw.
[]'s
Rodrigo
|
 |
|
|
Ficou show a solução.
E o DirtWatcherNullHandler assim...
Mas estou com algum problema com o guice devido a mudança na versão do VRaptor, eu acho.
|
 |
|
|
É lucas, isso tá dando trabalho.
Acabo de ler as classes...
Acho que não dá para simplesmente decorar os handlers. Na verdade, eu precisaria copiar o ReflectionBasedNullHandler e o GenericNullHandler (e.g.: MonjoReflectionBasedNullHandler e MonjoGenericNullHandler).
O ReflectionBasedNullHandler instancia o GenericNullHandler dentro do nullPropertyValue. Dentro do GenericNullHandler está a linha de código que preciso alterar...
No método nullPropertyValue ocorre a atribuição dessa instância recém criada.
Num tem como decorar isso
Alguma ideia!?
|
 |
|
|
Bom valeu a ajuda Lucas mas acho que infelizmente essa solução não serve
Ocorre o seguinte, a entidade que chega em tese é uma árvore de entidades com qualquer loucura de objetos (uma propriedade pode ser uma lista de entidades com lista de entidades). Então, eu não posso simplesmente criar só o proxy da entidade raíz. É preciso que todas entidades da árvore também sejam proxies. Verdade, eu poderia fazer isso na mão... Mas instanciar todos objetos de uma árvore na mão me parece muito esforço.
O ideal seria saber onde ocorre o class.newInstance e mudar esse ponto. Eu não sei se isso ocorre dentro do ognl, e se for não sei se é possível configurá-lo para que ele passe a usar meu proxifier.
[]'s
Rodrigo
|
 |
|
|
Pois é Lucas,
Depois de muita luta descobri que não seria assim tão fácil...
Pelo que eu entendi do código do VRaptor, o ParametersInstantiatorInterceptor faz duas coisas ( e por isso compromete uma solução mais simples).
1) Ele instancia uma floresta de objetos que será usada como parâmetros do método alvo no controller, no meu caso através do Ognl
2) Ele atribui às propriedade desses objetos os valores recebidos via parâmetros, no meu caso chamando os setters apropriado e fazendo as conversões necessárias
O problema é que a floresta de Objetos no passo 2 precisa ser uma floresta de proxies, porque depois que os setters já aconteceram o proxy já não funcionaria mais. A idéia do proxy é justamente interceptar essas chamadas de set*.
Talvez seja preciso configurar o Ognl para ele instanciar os proxies. Eu vi por cima a documentação do Ognl e parece que ele possui uma interface ClassResolver... o que me leva a um novo problema. Encontrar o código que recebe a class do ClassResolver, e que invoca o class.newInstace. Daí sim eu poderia alterar o código para usar um MonjoProxifier(class.newInstance) ...
Algumas dúvidas...
É mais ou menos isso que eu falei mesmo, ou estou viajando? Você acha que essa solução seria viável? Se sim, como/onde eu poderia alterar/configurar o Ognl para ele utilizar o MonjoProxifier?
[]'s
|
 |
|
|
Oi Lucas (herói do VRaptor )
Deixa eu esclarecer um pouco...
Eu utilizo um banco de dados não relacional chamado Mongo. Criei um framework para o mapeamento objeto - documentos chamado Monjo (https://github.com/rdllopes/monjo). Uma das features do Monjo é a habilidade dele fazer atualizações diferencias (leve em consideração que num banco não relacional um documento pode conter toda uma árvore de documentos). Isso é feito desprezando todas propriedades do objeto que não foram preenchidas. O problema é quando um usuário preenche uma propriedade com null (ou no caso do VRaptor, com uma String Vazia... ex: campo "Data de Despublicação" alterado de '01/07/2012' para '' e no Modelo a propriedade data de despublicação é do tipo Date...).
A solução mais simples (e porca) que vi seria adicionar uma propriedade com a lista de campos alterados em cada objeto e atualizar essa lista em cada um dos setters. Uma alternativa que achei razoável é utilizar AOP, mas isso forçaria todos usuários do Monjo a também utilizar aop.
Gostaria de saber se ao menos no VRaptor não seria possível resolver o problema de uma forma diferente.
[]'s
Rodrigo
|
 |
|
|