vRaptor - requisição Ajax post [RESOLVIDO]

Eai galera!

estou usando vRaptor no meu projeto e nao sei como “pegar” os dados da requisição Post Ajax no Java…

alguém pode me explicar como ficaria o método que vai pegar os dados no Java?

requisiçao Ajax post:$.ajax({ type:"post", url: "/meuProjeto/queroPegarOsDados", data: {codigo:125, nome:"Joaozinho"}, dataType: "json", beforeSend: function(xhr, settings){ alert("Antes de enviar!"); }, success: function(data, textStatus, xhr){ alert("Sucesso!"); }, error: function(xhr, textStatus, errorThrown){ alert("Erro!"); } });

Fica normal cara:

@Post("/queroPegarOsDados")
public void queroPegarOsDados(Long codigo, String nome){
// ... Faz o que precisa
result.use(Results.json()).withoutRoot().from(objetoQueVoceQuerRetornar).serialize();
}

$.ajax({ type:"post", url: "/meuProjeto/queroPegarOsDados", data: {codigo:125, nome:"Joaozinho"}, dataType: "json", // Isso diz que você espera um JSON do servidor beforeSend: function(xhr, settings){ alert("Antes de enviar!"); }, success: function(data, textStatus, xhr){ alert("Sucesso!"); }, // a variavel data vai ser o seu retorno do servidor, que no caso é um JSON error: function(xhr, textStatus, errorThrown){ alert("Erro!"); } });

Inclusive, dá para você fazer o seguinte:

// Modelo
public class Pessoa {
private Long codigo;
private String nome;
// getters e setters
}

// Controller
@Post("/queroPegarOsDados")
public void queroPegarOsDados(Pessoa obj){
// ... Faz o que precisa
result.use(Results.json()).withoutRoot().from(objetoQueVoceQuerRetornar).serialize();
}

// AJAX
$.ajax({  
    type:"post",  
    url: "/meuProjeto/queroPegarOsDados",  
    data: {'obj.codigo':125, 'obj.nome':"Joaozinho"},// repara que eu coloquei o nome entre aspas, pode ser dupla ou simples.
    dataType: "json",  
    success: function(data){ alert("Sucesso!"); },  // Dei uma simplificada aqui e no error... Eu não costumo usar os outros parâmetros...
    error: function(){ alert("Erro!"); }
});

-EDIT-
É legal colocar o @Post… se não, não funciona…

A intenção eh que quando o <select id=“cenario”> for selecionado, dispare a trigger ‘change’ e faça a requisição ajax, no java atualize o cenário selecionado e o coloque na sessão em usuarioWeb…

Ajax:[code]postJSON = function(url, data, dt, bs, s, e){
$.ajax({
type:“post”,
url:url,
data:data,
dataType:dt,
beforeSend:bs,
success:s,
error:e
});
};

							$("#cenario").change(function() {
								postJSON('/website/escolha',
									{id:$("#cenario option:selected").attr('id')},
									"json",
									function(xhr, settings){
										alert("Antes de enviar!");
									},
									function(data, textStatus, xhr){
										alert("Sucesso!");
									},
									function(xhr, textStatus, errorThrown){		    										
										alert("Erro!");
									}
								);
								
							}).trigger('change');[/code]

Java:@Post @Path("/escolha") public void escolherCenario(Long id) throws Exception { Cenario cenario = cenDao.consultar(Long.parseLong(id.toString())); this.usuarioWeb.setIdCenario(cenario.getId()); this.usuarioWeb.setTituloCenario(cenario.getTitulo()); result.redirectTo(CenarioController.class).manterCenarios(); }
o problema eh que mesmo quando consegue atualizar o cenário na sessão em usuarioWeb, sempre da o alerta de “Erro!”…

alguém sabe o porque que acontece isso??

Bom, existem algumas coisas que eu aconselho você a fazer:

@Post("/escolha") // Se você usa uma versão recente do VRaptor, não precisa colocar o @Path. Como está fica mais elegante. public void escolherCenario(Long id) { // Nunca faça throws nas actions, tenta barrar todas as exception aqui. try{ this.logger.debug("Recebeu o id com o valor: " + id); // use e abuse do log. Cenario cenario = cenDao.consultar(Long.parseLong(id.toString())); this.usuarioWeb.setIdCenario(cenario.getId()); this.usuarioWeb.setTituloCenario(cenario.getTitulo()); result.redirectTo(CenarioController.class).manterCenarios(); } catch(Exception e) { this.logger.error("Não foi possível escolher o cenário.", e);// Configure o Log4J para a sua aplicação e saia usando ele o tempo todo. result.use(Results.status()).badRequest("Não foi possível escolher o cenário."); // Envie uma badRequest que vai retornar o erro 500 com essa mensagem. } }
Você pode ainda, pelo Google Chrome ou pelo FireBug, olhar no console e ver o que eles te dão de informação sobre a requisição.

usando o firebug descobri o que acontece:

  • a requisiçao Ajax POST para “/escolha” cai no metodo Java e executa tudo normalmente, inclusive seta o cenario selecionado na sessao em usuarioWeb, mas o status eh 302 Moved Temporarily

  • o redirecionamento que esta no metodo Java para result.redirectTo(CenarioController.class).manterCenarios(); nao eh executado mas tem o status 200 OK
    e fica carregando… e nao para nunca…

Sera que isso explica o porque sempre cai no alerta de “Erro!” ?
O que eu to fazendo de errado?

Nesse caso vc não deveria fazer o redirect, só trocar pelo json…

agora se essa lógica é usada pra ajax e não ajax, vc vai ter que fazer de acordo com a request.

Humm… isso foi muito util…

Eu fiz assim e funcionou:

Ajax:[code]Essa eh a string que o metodo retorna agora: ${string}
<c:if test="${not empty usuarioWeb.listaCenarios}">
<select id=“cenario” name=“cenarios” title=“Selecione um cenário!” class=“tooltip”>
<c:forEach items="${usuarioWeb.listaCenarios}" var=“cenario”>
<c:if test="${cenario.id eq usuarioWeb.idCenario}">
<option id="${cenario.id}" selected=“selected”>${cenario.titulo}</option>
</c:if>
<c:if test="${cenario.id ne usuarioWeb.idCenario}">
<option id="${cenario.id}">${cenario.titulo}</option>
</c:if>
</c:forEach>
</select>
<script>
$(document).ready(function(){

								postJSON = function(url, data, dt, bs, s, e){
									$.ajax({
										type:"post",
							    		url:url,
							    		data:data,
							    		dataType:dt,
							    		beforeSend:bs,
							    		success:s,
							    		error:e
							    	});		    	    	
								};
								
								$("#cenario").change(function() {
									postJSON('/website/cenario/escolha',
										{id:$("#cenario option:selected").attr('id')},
										"json",
										function(xhr, settings){
											alert("Antes de enviar!");
										},
										function(data, textStatus, xhr){
											alert("Sucesso!");
										},
										function(xhr, textStatus, errorThrown){		    										
											alert("Erro!");
										}
									);
									
								}).trigger('change');
								
							});
						&lt;/script&gt;
					&lt;/c:if&gt;
					&lt;c:if test="${empty usuarioWeb.listaCenarios}"&gt;
						vazio
					&lt;/c:if&gt;[/code]

Java:@Post("/escolha") public void escolherCenario(Long id) throws Exception { try{ Cenario cenario = cenDao.consultar(Long.parseLong(id.toString())); this.usuarioWeb.setIdCenario(cenario.getId()); this.usuarioWeb.setTituloCenario(cenario.getTitulo()); //result.redirectTo(CenarioController.class).manterCenarios(); result.use(Results.json()).withoutRoot().from("Teste!").serialize(); }catch(Exception e) { result.use(Results.status()).badRequest("Não foi possível escolher o cenário."); // Envie uma badRequest que vai retornar o erro 400 com essa mensagem. } }

beleza, assim ta 100% funcionando!

mas eu tive que deixar de redirecionar para o método que eu precisava e passei a retornar uma String de teste para a tela…

bem, eu nao preciso que esse método retorne nada, e eu preciso que redirecione para aquele outro método…

entao como devo fazer meu método Ajax?

Bem, alem de nao precisar de retorno para a requisição Ajax, eu preciso que naquele método Java que postei antes, atualize a pagina atual…

tem como?

Eai pessoAll…

bem, percebi que nao tem como uma requisiçao Ajax nao ter um retorno do servidor, entao eu retorno sempre uma String vazia ("")…
e no metodo ‘success’ da requisiçao Ajax eu atualizo a pagina atual com a linha ‘location.reload();’ e com isso acabou com a necessidade de redirecionamento que eu havia pedido ajuda antes ^^

Obrigado a todos pela ajuda! ;D

Na verdade, você pode “retornar nada” mas informar que deu certo:

result.use(Results.status()).ok();