VRaptor: buscando o JSP do método inicial mesmo depois de um forwardTo

12 respostas
Spidey

Eu estou usando um método “fantasma” para exibir os resultados da minha busca independente do tipo de busca. Dessa forma, se a busca for simples ou completa (busca avançada), o JSP chamado é o mesmo. Acontece que, depois de um forwardTo, se eu não retorno simplesmente, mas ao invés disso, eu uso serialize para deixar minha aplicação mista (html e xml e json), o jsp chamado é o do primeiro método, o original da requisição, e não o jsp do método “fake”.

Acabei de testar tirando o result.use(Results.representation()).from(meu_objeto).serialize() e funcionou, o que me diz que o serialize não está levando em consideração o forward, tá ignorando-o.

12 Respostas

Lucas_Cavalcanti

vc quer fazer um forward E um serialize no mesmo método?

posta o código aqui, por favor (pelo menos as partes do result)

Spidey
@Get
@Path("busca.jsp")
public void metodo_legal(){
    result.use(Results.representation()).from(meu_objeto_que_eu_pego_do_result).serialize();
}

@Post
public void metodo_nao_legal(){
    //processo a minha lógica
    //incluo meus objetos legais na requisição
    result.use(Results.logic()).forwardTo(this.class).metodo_legal();
}

Na prática eu tenho um JSP que exibe o resultado da busca, e o resultado da busca é uma lista de objetos que eu embuto no result.
E tenho dois métodos, um pra busca simples, textual, e uma pra busca avançada, para buscar em cada membro dos objetos (não só pelo nome). Os dois métodos pega a lista de objetos filtrados, adicionam na requisição, e "redirecionam", por forward, pro método da busca pra mostrar a página padrão.
Se não fosse o fato de eu querer que a serialização aconteça, poderia usar pageOf, mas não é o caso, preciso que a lógica seja sim processada (afinal, o serialize é feito pelo VRaptor, e não pelo JSP).

Lucas_Cavalcanti

no seu metodo_legal, vc quer que ele redirecione pra jsp padrão?

vc chama esse metodo_legal para ser serializado em xml ou json também?

Spidey

Isso, eu quero que quando caia no metodo_legal() a requisição retorne ou o WEB-INF/jsp/meuController/metodo_legal.jsp, ou então serialize se receber a requisição com o _format ou accept.

edit: desculpe-me os erros de português, acabei de editar para corrigi-los, a frase anterior estava caótica.

Lucas_Cavalcanti

entendi qual é o problema… consegui simular aqui

o problema é que o result.forwardTo(…) não faz o forward de verdade… ele executa o outro método dentro do primeiro, e qdo o representation() pede pra usar a jsp padrão ele usa a do primeiro método.

o ideal na verdade, como vc está vindo de um @Post é fazer um redirect, e não um forward. O redirect vai funcionar.

Spidey

Mas no redirect eu vou perder os parâmetros. Eu posso fazer um redirect passando os parâmetros?

Lucas_Cavalcanti

o redirect não perde os parâmetros, pode fazer tranquilo.

public void meuMetodo() {
    result.include("isso", permanece);
    result.redirectTo(this).outroMethod(isso, tambem);
}
Spidey

Engraçado, tinha parte do código usando redirectTo já. Mas como que isso funciona? O redirect não vai causar outro request feito pelo browser? O VRaptor guarda essa informação na memória pra incluir na próxima requisição?

E outra, o session eu até concordo de por no construtor, mas botar o _format em todos os métodos me quebrou as pernas. E não faz sentido botar ele como membro do controller e só setá-lo e lê-lo quando necessário, faz? O problema é que botando o String _format no método genérico, no metodo_legal(), todos os outros métodos que fazem redirect pra ele precisam também ter o _format na assinatura, ou então pega ele do RequestInfo, que é justamente o que eu estou deixando pra trás.

Pensando bem, acho que forwardTo no meu caso é mais interessante do que redirectTo, porque no redirect existe realmente um redirect, e daí um F5 no site estraga a view da busca (retorna uma busca vazia).

Lucas_Cavalcanti

buscas não deveriam ser post, deveriam ser get. Assim os parâmetros ficam na url e vc consegue dar F5 normalmente (e o browser não vai abrir um dialog perguntando se vc quer mesmo dar F5)

só o metodo_legal faz a busca de verdade, ou os outros fazem busca também?

vc não deveria precisar do _format, quer me passar o código desse seu controller por MP, assim eu te falo se tem um jeito melhor de fazer? vc pode usar um private GIST http://gist.github.com

Spidey

Tá no pastebin. http://cwtools.pastebin.com/dxM9Bqp4
O projeto é open source mesmo, dá nada.

A busca é feita em vários métodos: buscaFoto() e buscaFotoAvancada() e buscaFotoPorId() (mas que na verdade é por tag, lol). O resultado é embutido no result e então chama o busca(). Vou ver se passo a busca pra GET mesmo, mas no caso da busca avançada não fica legal.

Ainda não entendi como que o redirect, digo, o método redirecionado, recebe os parâmetros do result. Os parâmetros do método dá pra pensar que o redirect manda embutido no request de redirect, mas os parâmetros do result ficou um mistério na minha cabeça.

Lucas_Cavalcanti

o vraptor faz uma mágica pra fazer isso funcionar (salva tudo na sessão e pega na próxima request)

Lucas_Cavalcanti

bom, vamos lá:

  • se vc quer internacionalizar as mensagens, vc pode usar o new I18nMessage() ao invés do ValidationMessage, daí as mensagens podem ficar no messages.properties

  • acho que se vc criar essa classe vai resolver o seu problema:

@Component
public class HTMLSerialization implements Serialization {

	private final Result result;
	private final TypeNameExtractor extractor;

	public HTMLSerialization(Result result, TypeNameExtractor extractor) {
		this.result = result;
		this.extractor = extractor;
	}

	public boolean accepts(String format) {
		return "html".equals(format);
	}

	public <T> Serializer from(T object, String alias) {
		result.include(alias, object);
		if (!result.included().containsKey("fotos"))
			result.use(page()).defaultView();
		return new IgnoringSerializer();
	}

	public <T> Serializer from(T object) {
		result.include(extractor.nameFor(object.getClass()), object);
		if (!result.included().containsKey("fotos"))
			result.use(page()).defaultView();
		return new IgnoringSerializer();
	}

}
Criado 24 de fevereiro de 2011
Ultima resposta 24 de fev. de 2011
Respostas 12
Participantes 2