Migrando de VRaptor 2 para 3 - Dúvida Ajax

Olá,

Estou migrando do VRaptor2 para o 3 e estou com uma dúvida sobre como criar requisições ajax. Como não achei a documentação desta parte muito intuitiva, resolvi postar aqui.
No VRaptor2 eu simplesmente anotava um método com a annotation @Remotable e realizava uma requisição para “action.metodo.ajax.logic” para realizar a requisição. O framework automaticamente parseava todos os objetos a serem ejetados para JSON.
No VRaptor3, eu realizo a requisição para qual URL?
E eu sempre terei que criar um “descritor” para a resposta JSON (/WEB-INF/jsp/action/metodo.json.jsp)? (se for desta maneira mesmo, eu preferia da maneira q era feito no 2 - era mais produtiva)

Obrigado.

oi ACDias. Estamos lancando na versao 3.0.2 um suporte inicial ao JSON/XML para AJAX sem ter de criar um jsp para tal. Deve sair essa semana ainda!

No VRaptor3 vai ser a requisição para a URL normal, a mesma que você usaria se o resultado for uma jsp

Uma gambiarra que você pode fazer até esperar uma nova implementação é criar teu JSON dentro do método do controller e jogar para a saída como String mesmo. No meu caso eu criei um interceptor que intercepta (que redundante, hehe) todos métodos onde o retorno é um JsonObject (json.org/java), e então faço a impressão o jogo para o browser.

Silveira, outro dia você comentou na issue os planos de usar xstream. Vocês farão algo que possa gerar tanto XML como Json? Ou apenas Json?

[quote=garcia-jj]
Silveira, outro dia você comentou na issue os planos de usar xstream. Vocês farão algo que possa gerar tanto XML como Json? Ou apenas Json?[/quote]

Olá garcia,

isso já foi implementado, com o XStream por tras, está disponível no snapshot do repositório… e gera tanto xml quanto json:

result.use(json()).from(objeto).include("fieldNaoPrimitivo").exclude("fieldPrimitivo").serialize();
//ou
result.use(xml()).from(objeto).include("fieldNaoPrimitivo").exclude("fieldPrimitivo").serialize();

o suporte ainda é básico, são serializados por padrão todos os campos primitivos do objeto (String, números, enums e datas)
e você pode incluir os campos não primitivos com o include, e excluir os primitivos com o exclude…

[]'s

Faz anos que não acompanho o xstream, mas antigamente tinha um problema quando a ele precisar de permissões no security manager para criar classloaders (isso em JVM compartilhadas, onde o security manager é muito restrito)? Ainda é necessário ter o XPP3 ou instanciar o DOM driver manualmente? Para JSON será usado o Jetinson?

Olhei hoje por cima como ficou a implementação, ficou muito bom.

Abraços, e obrigado.

Q maravilha, rs, acabei de terminar uma implementação usando xstream q tinha de exportar um monte de coisas em xml, hehehe se eu tivesse uma semana a mais de prazo teria ganho alguns dias, rs

Depois com tempo vou testar essa versão aqui, pois eu tenho algumas situações bem chatas de objetos bidirecionais q foi meio chato para tirar as referencias circulares sem contar q ficou feio, sem contar q eram entities do hibernate então tem coleções lazy para todos os lados.

exemplinho de cabeça, tem suporte ?

class Parent {
  List<Child> childList;
}

class Child {
  Parent parent;
}

sendo objet do tipo Parent, 
result.use(json()).from(objeto).include("childList").exclude("childList.parent").serialize();   

@garcia-jj
Eu tive problemas em usar o xstream no gae, mas era algo bem especifico, se não me engano algo relacionado ao reflection, tem ou pelo menos tinha issue no site do xstream, mas até a ultima vez q eu vi ainda não tinham previsão de suporte completo para o gae, aí eu tive de compilar a minha versão do xstream com umas coisinhas a mais.

@vraptor-team
Parabéns !

@garcia-jj
Estamos usando o XStream normal, portanto com o XPP parser, e para JSon estamos usando o JSonHierarchicalDriver, que não precisa do jettinson…
Mas você pode estender o serializer e criar o XStream do jeito que você quiser, passando outro ReflectionProvider, outro Driver, etc…

@Edufa
esse código que você passou funciona sim (ou pelo menos deveria, talvez tenha que adicionar alguns testes para listas de elementos):

result.use(json()).from(objeto).include("childList").exclude("childList.parent").serialize();

de qqer forma esse vai ser o jeito de excluir elementos… passando o caminho deles a partir do objeto principal

@Edufa
agora funciona para collections também, com algumas limitações do XStream, mas funciona… (use implementações padrão de lista (ArrayList, LinkedList, etc)

[quote=lucascs]Estamos usando o XStream normal, portanto com o XPP parser, e para JSon estamos usando o JSonHierarchicalDriver, que não precisa do jettinson…
Mas você pode estender o serializer e criar o XStream do jeito que você quiser, passando outro ReflectionProvider, outro Driver, etc….[/quote]

Essa é uma das razões mais fortes de eu amar o vraptor. Está tudo lá, mas se você não gostar pode facilmente mudar com apenas uma simples classe Java.

Eu tive problemas com o xstream há algum tempo quando precisei implantar um projeto em um cliente, onde a jvm era compartilhada, então as policies eram bem rígidas. O rolo que eu tive foi quando a permissões de classloader (não lembro exatamente), então tive que usar outro parser.

Abraços

Voltando um pouco o assunto, antes no vraptor 2 chamava assim:

retirar: function(id) {
			$.ajaxJson({
					    url: 'ajax.retirar.ajax.logic',
					    data: { 
							'id': id
								  },
						success: 
							function(data) {
								alert("funcionou");
							}
					});
			}

Agora no VRaptor3 mudei para:

retirar: function(id) {
			$.ajaxJson({
					    url: 'ajax/retirar',
					    data: { 
							'id': id
								  },
						success: 
							function(data) {
								alert("funcionou");
							}
					});
			}

Entrou no método retirar e fez tudo certo, porém não voltou para o success. Como fica isso com o VRaptor3?;

toma cuidado com os caminhos relativos…

vc vai precisar colocar o contexto na url…

url : '<c:url value="/ajax/retirar" />'

Não rolou, a url está certa. Entrou no meu Controller e executou tudo certo e só isso. Não voltou para o success do Json. Vi que tem o JsonOutjecter, tenho que usar isso? (só um chute)

Se vc tiver o Firefox, instala o Firebug nele e vê qual é o status que essa chamada ajax está retornando… se estiver dando 404 ou 500 não vai pro success…

ou da uma olhada no log pra ver se ele tá tentando redirecionar pra jsp do método (não deveria fazer isso)…

Está retornando 200 e não está retornando pra jsp

se retornou 200 deveria ter ido pro success… tenta chamar a url na mão, e ver se ele tá retornando o json direitinho… talvez seja alguma configuração perdida desse $.ajaxJson…

tenta trocar pra $.getJSON ou simplesmente $.ajax com a property type: ‘json’

Com $.getJSON entrou no sucess antes de entrar no Controller, e quando terminou o método na classe Controller não aconteceu nada.

o jeito de usar o getJSON não é do mesmo jeito… é assim:

var resposta = $.getJSON(url, parametros);
//faça aqui o que vc faria no success
var nome = resposta.usuario.nome;
...

Continuou a mesma coisa, mas agora eu fui ver que com o $.ajaxJson está indo como ‘POST’ em vez de ‘GET’

como assim continuou a mesma coisa? posta o código que vc tá usando plz?