[RESOLVIDO] Dúvida JQuery + JSON + result do VRaptor

9 respostas
G

Boa tarde a todos, tenho a seguinte arquitetura:

$(".botao-acao").click(function(){
		if(validarForm()){
			var formJSON = getJSON($("#form-geral")); //método que serializo meu formulário e o transformo em um json 
			
			var acao = $(this).data("action"); // /cliente/salvar
			var metodo = $(this).data("metodo"); // 'POST'
			
			ajaxSubmit(metodo, acao, formJSON, function(resultadoEmJSON){
                                //  AQUI ESTÁ O MEU PROBLEMA: COMO RECEBER O RESULTADO COMO JSON E RENDERIZAR OS RESULTADOS?
				alert(resultadoEmJSON.toSource());
				setGeralMensagens(msg, "Sucesso", CLASSE_SUCESSO, IMG_SUCESSO);
                               
			});
		}
	});
	
	function ajaxSubmit(metodo, acao, form, callback){
		$.ajax({
			type: metodo,
			url: acao,
			data: form,
			success: callback
		});
	}

E no controlador tenho:

@Post("/cliente/salvar")
	public void salvarCliente(Cliente cliente){
		try {
			cliente = clienteBO.salvar(cliente);
			result.include("message", "Cliente salvo com sucesso!")
				  .include(cliente).forwardTo(this).clienteMan();

			//result.use(Results.json()).withoutRoot().from(result).serialize();  
		} catch (BusinessException e) {
			e.printStackTrace();
			result.include("error", e.getMessage()).forwardTo(this).clienteMan();
		}
		
	}

A minha dúvida é relativa ao callback da requisição ajax. Gostaria de saber como faço para receber os dados incluídos no objeto result do controlador em JSON para poder manipulá-los e como renderizar o resultado após a manipulação dos dados (json)?

Por exemplo: quero poder pegar o cliente do result da seguinte forma para então exibir seu nome junto com a message no meu dialog: (claro que eu poderia colocar o nome do cliente no result do controlador, este é apenas um exemplo)
var msg = resultadoEmJSON.cliente.nome;

Para ilustrar, o dialog:

<div id="dlg-mensagens">
		<span id="imagem-dlg" style="float:left; width:80px"></span>
		<label id="mensagem-dlg">
			<c:if test="${not empty error}">${error}</c:if>			
			<c:if test="${not empty message}">${message}</c:if>	
		</label>	
	</div>

9 Respostas

L

se vc quer o result em json vc precisa usar:

result.use(Results.json()).from(objeto, "nome").serialize();

o result.include não vai funcionar nesse caso.

G

Primeiramente obrigado pela atenção e ajuda! Você poderia me explicar um pouco a respeito do result.use(Results.json()).from(objeto, "nome").serialize(); por exemplo, como vc pode ver ali em cima no meu código comentado, eu até tentei utilizar ele passando o objeto result mas n tive resultados. Se eu quiser passar vários objetos como por exemplo o cliente, uma mensagem, uma lista contendo outros clientes como seria? Teria que fazer como o exemplo a seguir?

result.use(Results.json()).from(objeto1, "nome1).serialize(); result.use(Results.json()).from(objeto2, "nome2").serialize(); result.use(Results.json()).from(objeto3, "nome3").serialize();

Ou teria que criar um objeto de retorno contendo tudo que preciso?

W

Acredito que teria que criar um objeto, que pode ser uma coleção (lista, map) ou um tipo que você definir.

L

se vc quer passar vários objetos vc precisa criar uma classe que agrupe esses objetos…

G

Pessoal bom dia, dand continuidade a minha dúvida e conforme entendimento das explicações fiz a seguinte implementação:

Criei um DTO genérico:

private String tituloDialog;
	private String mensagem;
	private ImagensRetorno classeImagem; //enum
	private MensagemRetorno classeMensagem; //enum
	private Status status; //enum
	private T objeto;
	private List<T> lista;

        //gets sets...

Alterei o método salvar e criei o método para despachar o retorno:

@Post("/cliente/salvar")
	public void salvarCliente(Cliente cliente){
		try {
			cliente = clienteBO.salvar(cliente);
			despacharResposta("Sucesso", "Cliente salvo com sucesso!", ImagensRetorno.IMG_SUCESSO, MensagemRetorno.CLASSE_SUCESSO, Status.SUCESSO, cliente, null);
		} catch (BusinessException e) {
			e.printStackTrace();
			despacharResposta("Atenção", "Erro ao tentar salvar o cliente, contate os responsáveis pelo sistema! Motivo: "+e.getMessage(),
					ImagensRetorno.IMG_ERROR, MensagemRetorno.CLASSE_ERROR, Status.ERRO, null, null);
		}
		System.out.println("passou pelo salvar");
	}
	
	private void despacharResposta(String titulo, String mensagem, ImagensRetorno classeImagem, MensagemRetorno classeMensagem, 
			Status status, Cliente cliente, List<Cliente> lista){
		GenericDTO<Cliente> dto = new GenericDTO<Cliente>();
		
		//mensagem e título do dialog de retorno
		dto.setTituloDialog(titulo);
		dto.setMensagem(mensagem);
		
		dto.setClasseImagem(classeImagem);
		dto.setClasseMensagem(classeMensagem);
		
		dto.setObjeto(cliente);
		dto.setLista(lista);
		dto.setStatus(status);
		
		result.use(Results.json()).from(dto, "resultados").serialize();
	}

E no javascript:

ajaxSubmit(metodo, acao, formJSON, function(resultados){
				alert(resultados.toSource());
				alert(resultados.mensagem);
				processarResultados(resultados);
			});

function processarResultados(resultados){
		alert(resultados.mensagem);
		var teste = resultados.mensagem;
		alert(teste);
		setGeralMensagens(resultados.mensagem, resultados.tituloDialog, resultados.classeMensagem, resultados.classeImagem);
	}

Não funcionou muito bem porquê no json resultados do lado do javascript. O meu objeto cliente não aparece no toSource do resultado e meus enuns não são objetos do tipo classeImagem{name:"xyz", descricao:"abc"} como pode ser visto logo a seguir e também nos demais alertas quando tentei acessar as propriedades do json gerado todos retornaram null (undefined). Um detalhe: não achei nada elegante!

({resultados:{tituloDialog:"Sucesso", mensagem:"Cliente salvo com sucesso!", classeImagem:"IMG_SUCESSO", classeMensagem:"CLASSE_SUCESSO", status:"SUCESSO"}})
L

retornou tudo null pq o json tem root… vc deveria fazer resultados.resultados pra funcionar ou mudar a chamada do result pra:

result.use(Results.json()).withoutRoot().from(dto).serialize();
G

Lucas obrigado pela ajuda, segui suas dicas e encontrei em outro post tbm a respeito de serialização de json a respeito do recursive(), adicionei ao meu método que despacha o resultado e agora deu tudo certo. Segue a solução da serialização do meu objeto dto em json:

result.use(Results.json()).withoutRoot().from(dto).recursive().serialize();
Obs.: sem root para poder acessar os valores do json diretamente e recursivo para serializar também os modelos como no meu caso a classe Cliente.

Só uma dúvida a respeito da serialização do enum (que não vai ser um problema pois eu posso mudar pra string no meu dto):

Tenho este enum:

public enum TipoPessoa {
	
	PF("Física"),
	PJ("Jurídica");
	
	private String descricao;
	
	private Status(String descricao){
		this.descricao = descricao;
	}
	
	public String getDescricao(){
		return this.descricao;
	}
	
}

Ele não teria que ser serialido como um objeto como por exemplo [...]classeImagem:{name:"PF", descricao:"Física"}[...] ?

L

o serializador de enum usa o nome da constante…

se vc quiser que ele serialize o nome e a descrição, vc precisa criar um converter

algo assim:

@Component
public class TipoPessoaConverter implements Converter { //do XStream
    // canConvert retorna true se for TipoPessoa.class

    // unmarshall pode deixar em branco

    // marshal vc pega o objeto e usa o writer pra dar um .startNode("name"), setValue(xxx) e depois .endNode
}
G

Resolvido, vlw pela ajuda :smiley:

Criado 8 de março de 2013
Ultima resposta 11 de mar. de 2013
Respostas 9
Participantes 3