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

Boa tarde a todos, tenho a seguinte arquitetura:

[code]$(".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
	});
}

[/code]

E no controlador tenho:

[code]@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();
	}
	
}

[/code]

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)

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>

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.

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?

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

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

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:

[code] private String tituloDialog;
private String mensagem;
private ImagensRetorno classeImagem; //enum
private MensagemRetorno classeMensagem; //enum
private Status status; //enum
private T objeto;
private List lista;

    //gets sets...

[/code]

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

[code] @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();
}[/code]

E no javascript:

[code]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);
}

[/code]

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!

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();

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:

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:

[code]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;
}

}[/code]

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

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
}

Resolvido, vlw pela ajuda :smiley: