VRaptor 3 - Como inferir o tipo de dado (XML/JSON/HTML) pedido?

Eu tenho uma lógica com @Path(“nome”) que redireciona para outra com @Path(“nome/”). Uso isso para que eu possa usar links relativos nos jsps pra facilitar minha vida.
Enfim. O problema é que quando eu mando uma requisição para nome?_format=xml, a lógica redireciona para nome/, mas não carrega o _format nem nada. Queria uma forma de inferir o _format da requisição atual, para poder redirecionar de acordo.

Tentei UserInfo#getRequest#getParameter("_format") mas não rolou.

se vc faz o redirect os parâmetros são perdidos…
de qqer forma vc pode receber um HttpServletRequest no construtor e chamar request.getParameter("_format"). deveria funcionar

o jeito de fazer isso funcionar é mandando o header “Accept: application/xml”, mas acho que isso vai complicar mais as coisas :wink:

vc pode me falar melhor como vc tah usando os links relativos na jsp pra eu ver se tem uma solução melhor do que o redirect?

O esquema dos links relativos é que antes eu fazia um método só recebendo 2 paths: “” e “/”. Mas daí se eu caio pelo “” (tem um @Path no controller, por isso eu to usando “” mesmo), meus links, que são “register”, ${classe.id} e outros, não funcionam.

Minha aplicação tá assim:
/repository -> listagem de repositórios, mas cai no debaixo
/repository/ -> idem ao de cima, mas aqui que tem a lógica mesmo
/repository/register -> formulário de registro de novo repositório e lógica de inserção no banco (GET e POST)
/repository/${repository.name} -> edit de repositório, com prioridade menor que o register

Daí na listagem, ou seja, em /repository/, o meu link para registrar novos repositórios é somente. Sem o método do “index”, redirecionando do “” pro “/”, o mesmo link, o “register”, iria mandar para “/register” ou invés de “/repository/register”.

pq não usar o <c:url ? ou os caminhos mais completos? ou ainda não registrar o path /repository?

Não entendi. Como usaria o c:url nesse caso?
E não uso caminho absoluto porque o nome da aplicação pode mudar, não? Atualmente, eu acesso por http://localhost:8080/meu-projeto/repository/. Mas se, futuramente, eu quiser mudar para http://localhost:8080/repository/, os links /meu-projeto/repository ficam quebrados.

Eu tava querendo evitar de botar o root da aplicação numa variável. O c:url resolve isso pra mim? Se sim, seria ótimo.

sim, o c:url resolve:

<a href="<c:url value="/repository" />">Listagem</a>

assim ele vai colocar o context-path no começo da URI, ou seja, ela é absoluta em relação ao context-path.

Upando o tópico porque a mesma dúvida agora apareceu.

Eu tenho um form de upload de objetos X. O form redireciona pra ele mesmo, de forma que eu possa fazer vários uploads em sequência, sem ter que ficar clicando em link de upload. Simplesmente preencho o form, posto, preencho denovo, e assim por diante. Essa funcionalidade eu não quero/posso mudar.
Preciso que esse mesmo post, com _format ou usando o header, ao invés de retornar um form (que em XML não faz nenhum sentido), retorne apenas o próprio objeto recém inserido no banco.

Basicamente meu código tá assim:

[code]
@Path("/registra")
@Get
public void registra(){
//carrega o registra.jsp
}

@Path("/registra")
@Post
public void registra(Objeto x){
dao.save(x);
results.use(Results.logic()).redirectTo(this.class).registra();
}[/code]

Queria poder fazer um if antes do redirect, e caso seja um pedido de XML, retornar apenas o x, já salvo, serializado.

um jeito que funcionaria, já que os dois métodos têm o mesmo nome, é:

results.use(Results.representation()).from(x).serialize();

se vc passar _format=xml (ou o header Accept) ele renderiza xml, se deixar do jeito que o browser faz, ele renderiza a jsp

o único chato é que ele não faria um redirect.

Acabei de upar um outro tópico com outra dúvida, mas aqui tá mais centralizado e evita o off-topic.

Tem como eu comparar o Results.representation() com alguma classe padrão? Sei lá, Results.representation() == Results.json().class, sei lá.
Vou debugar minha aplicação pra ver isso AGORA!

Results.representation() é estático

o que seria diferente se for json?

Um redirect, por exemplo.
Quando eu acabo de fazer um upload de arquivo, se for pelo browser, eu retorno pra listagem, se for por json/xml eu quero retornar o objeto recém adicionado serializado.
Acho melhor do que criar outro método e ficar poluindo o controller, saca?

Mas pelo que estou vendo, acho que dá pra resolver com métodos extras em certos casos e usar o Results.representation() mesmo na maioria. Valeu.

[quote=Spidey]Eu tenho uma lógica com @Path(“nome”) que redireciona para outra com @Path(“nome/”). Uso isso para que eu possa usar links relativos nos jsps pra facilitar minha vida.
Enfim. O problema é que quando eu mando uma requisição para nome?_format=xml, a lógica redireciona para nome/, mas não carrega o _format nem nada. Queria uma forma de inferir o _format da requisição atual, para poder redirecionar de acordo.

Tentei UserInfo#getRequest#getParameter("_format") mas não rolou.[/quote]

Acho que vc não esta conseguindo pois há uma diferença entre redirecionamento e encaminhamento, o ideal seria vc olhar a documentação ho vraptor pra entender essa diferença.

pbnf, você tem razão mas essa não é a mais a questão, o tópico segue no assunto do título e do meus últimos posts.

pra descobrir qual é o tipo:

-se vc está usando o _format, basta receber um parâmetro no método chamado _format:

public void minhaLogica(...., String _format) {
    ....
}

-se vc está usando o header Accept, vc precisa receber um HttpServletRequest no construtor, e fazer:

request.getHeader("Accept").contains("json"); // ou algo do tipo

Nossa, bem pensado. Eu fiz uma “gambi” legal, peguei o _format do RequestInfo, pelo getAttribute(). De qualquer forma, seria legal se o VRaptor disponibilizasse uma função que retornasse um inteiro (e tivesse umas constantes pra comparação) que identificasse o tipo de requisição (html, xml ou json).

receber o parâmetro _format já seria o suficiente. A gente pode fazer o VRaptor adicionar esse parâmetro _format mesmo que tenha vindo o header Accept.

Só pra saber, vc tirou o RequestInfo né?

PS: no java 5+ não tem mais motivos pra gente usar inteiros e constantes, enums são bem mais apropriadas :wink:

Como assim tirou o RequestInfo? Você quer dizer se eu tirei do exemplo, mas que na verdade tá no meu construtor? Se for, sim, tem sim.

Sendo o WidgetInfo um componente do meu código.

E sim, usa enums então, melhor mesmo. É que eu trabalho com Android também e no Android é tudo por int, raramente vejo um enum. Enums no java tem nome ou rola enum anônimo igual em C?

enum tem que ter nome em java…

vc ainda usa o RequestInfo pra alguma coisa?

Pra pegar variáveis de sessão e pra pegar o _format. Porque você tá perguntando, ele está sendo deprecated?

não isso… para o _format vc não precisa do RequestInfo, vc pode receber o _format direto no método…

se vc precisa pegar variáveis da sessão, receba o HttpSession direto, não o RequestInfo…

ele não é deprecated, mas vc deveria evitar usá-lo