Recentemente eu postei um tópico querendo saber como eu configurava uma url para erro 404. O problema é que o Vraptor só permite tratar erros 404 com páginas estáticas. Quando a gente coloca uma url que vai ser tratada por um controller, não funciona. O tópico em questão era esse aqui: http://www.guj.com.br/java/304932-pagina-de-erro-personalizada-no-vraptor#1621778
Eu dei uma olhada no código do Vraptor e encontrei o problema. Acredito ser um bug. Quando a gente acessa uma url que não existe, o filtro do Vraptor é acionado 2 vezes: a primeira acontece por conta do dispatcher REQUEST e a segunda por conta do dispatcher ERROR. Nessa segunda vez, a requisição que chega no filtro está procurando pela URL configurada no web.xml.
O problema é que, quando o fluxo de execução chega na classe DefaultResourceTranslator, a requisição está procurando pela URL que não existe. Em algum momento ocorre essa mudança e acredito que isso seja um erro.
Para reproduzir o erro, coloque a seguinte configuração no web.xml:
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
Além disso, adicione o dispatcher de ERROR no filter-mapping.
Depois coloque um breakpoint na linha 93 da classe VRaptor e na linha 48 da classe DefaultResourceTranslator. Inicie o servidor e tente acessar uma URL inválida. Quando passar a primeira vez pelos breakpoints, pode pular, pois são referentes ao dispatcher REQUEST. Na segunda vez que passar pelos breakpoints, inspecione a instância de RequestInfo e perceba que a requisição mudou de um momento pro outro.
Só pra testar, eu coloquei o seguinte trecho de código na classe DefaultResourceTranslator:
if(info.getRequest().getDispatcherType().equals(DispatcherType.ERROR)) {
resourceName = "/404";
}
E funcionou… O problema é que eu não consegui resolver o problema na raiz… Não era pra chegar uma outra requisição aí. Seria um bug de fato? Se sim, como posso resolvê-lo?
Oi Lucas, eu baixei aqui o Vrapter 3.5.3 e continua com o mesmo problema. Em algum momento no meio da aplicação a instância de RequestInfo muda. Eu testei acessar URLs válidas para ver se esse era um comportamento padrão do framework e eu percebi que não. Todas as URLs que eu acessei e a página carregou com sucesso, a instância de RequestInfo era a mesma nos 2 lugares que eu falei. Eu acredito que esse é justamente o problema de não ser possível configurar uma URL de erro 404 que passa por um controller.
PS: quando eu baixei o source do maven, eu tive que montar a estrutura de diretórios do projeto “na mão”… era pra ser assim mesmo? ou tinha alguma forma automática?
Não entendi muito bem… Se eu der um attach source do vraptor 3.5.3 no projeto do vraptor 3.5.4-SNAPSHOT e mandar debuggar ele vai usar o código do 3.5.3? E se eu não mandar debuggar, vai usar o código do 3.5.4-SNAPSHOT?
Não muda… O problema é justamente esse: nas 2 vezes que fluxo de execução passa por ali request.getRequestURI() retorna /vraptor-blank-project/sbrubbles…
Mas o que eu to achando estranho é que a requisição que chega no filtro do Vraptor está buscando por /404 (que é o correto)… Mas no meio do código essa requisição muda pra /sbrubbles de novo… E é isso que não devia acontecer…
[quote=Lucas Cavalcanti]e esse cara? javax.servlet.error.request_uri
o que tem dentro dele?[/quote]
Retorna “/vraptor-blank-project/sbrubbles”
É um atributo que eu consigo ver inspecionando a variável, mas que não é retornado em request.getAttributeNames(). Já procurei bastante pela net e não consegui pegar o valor desse atributo… Acho que a única maneira seria usando reflection. Mas isso seria uma forma ruim de resolver o problema. Ainda acho que a raiz do problema é que a request muda no meio da execução. Isso não faz sentido. Se você tiver Skype posso compartilhar minha tela e explicar melhor o que eu to falando…
Abra a classe VRaptor,
coloque um breakpoint no começo do doFilter,
inspecione o request tanto na primeira requisição quanto no 404… e veja se nesse segundo request existe alguma maneira de pegar a URI /404.[/quote]
Dá sim… Isso ilustra o que eu to falando… A requisição muda no meio da execução… Assim que entra no filtro eu tenho uma requisição, lá pro meio da execução eu tenho outra… Oo