VRaptor 3 + JSON

a classe de json sua estende XStreamJSONSerialization?

se sim, basta anotá-la… e usar result.use(Results.json()).from(objeto)…serialize();

Se você usou a implementação que o lucas te indicou no inicio do topico, você não precisa injetar ela dentro de sua classe. Pelo que entendi foi isso que você fez, não?

O correto seria apenas colocar seu componente em algum lugar que o vraptor possa fazer scan, e no seu controller escrever normalmente conforme o padrão do vraptor que é ± assim:

public class MeuController { public void metodo() { result.use(Results.json()).from(objeto).serialize(); } }

Abraços

Lucas eu usei result.use(json()), mais dessa forma ele esta mandando “list” também, e como vc colocou no inicio do tópico eu criei a classe que tira o “list” do objeto json. E minha classe não extende XStreamJSONSerialization.

Garcia, isso mesmo o this.json é minha classe injetada no meu controller. Agora onde iria colocar minha classe para fazer o que vc colocou, “o vraptor fazer o scan”.

Essa página, ela é de pesquisa. Com os campos para filtros e uma tabela, no meu metodo do controller pesquisar, ele esta anotado como @Get e @Post, dessa forma eu utilizo o mesmo método para trazer a lista completa no primeiro acesso, daí caso o usuário queira refinar os dados ele informa os filtros necessários.

Então Lucas, logo no carregamento da página me aparece o arquivo para donwload, eu necessariamente nem preciso chamar o método do meu controller via requisição ajax.
No meu controller o método esta assim:

        @Post
	@Get
	@Path("/cooperado.pesquisar")
	public void pesquisar(Cooperado cooperado){
		List<Cooperado> cooperados = this.service.pesquisar(cooperado);
		
		this.json.from(cooperados).serialize(); //dessa forma acontece o erro já informado - Cannot forward after response has been committed 
                //result.use(Results.json()).from(cooperados).serialize();  // assim o objeto json vem com root "list"
           //nas duas formas aparecem o arquivo para download.

	}

faça essa classe de JSON que vc fez implementar JSONSerialization:

@Component
public class MinhaClasseQueFazJSON implements JSONSerialization {

....
}

assim ela vai ser usada no result.use(json())

[]'s

Minha classe esta assim:


import java.io.Writer;

import javax.servlet.http.HttpServletResponse;

import br.com.caelum.vraptor.interceptor.TypeNameExtractor;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.serialization.XStreamJSONSerialization;

import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;

@Component
public class CustomJSONSerialization extends XStreamJSONSerialization {

	public CustomJSONSerialization(HttpServletResponse response,
			TypeNameExtractor extractor) {
		super(response, extractor);
		// TODO Auto-generated constructor stub
	}

	@Override
	   protected HierarchicalStreamDriver getHierarchicalStreamDriver() {
	       return new JsonHierarchicalStreamDriver() {
	            public HierarchicalStreamWriter createWriter(Writer writer) {
	                  return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
	            }
	       };
	   }
}

No caso de implementar a interface JSONSerialization, como ficaria as implementações dos metodos abaixo?

[code]@Override
public boolean accepts(String arg0) {
// TODO Auto-generated method stub
return false;
}

@Override
public <T> Serializer from(T arg0) {
	// TODO Auto-generated method stub
	return null;
}

@Override
public <T> Serializer from(T arg0, String arg1) {
	// TODO Auto-generated method stub
	return null;
}

[/code]

A classe CustomJSONSerialization seria o que eu estou utilizando em this.json.

[quote=davisnog]Minha classe esta assim:


import java.io.Writer;

import javax.servlet.http.HttpServletResponse;

import br.com.caelum.vraptor.interceptor.TypeNameExtractor;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.serialization.XStreamJSONSerialization;

import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;

@Component
public class CustomJSONSerialization extends XStreamJSONSerialization {

	public CustomJSONSerialization(HttpServletResponse response,
			TypeNameExtractor extractor) {
		super(response, extractor);
		// TODO Auto-generated constructor stub
	}

	@Override
	   protected HierarchicalStreamDriver getHierarchicalStreamDriver() {
	       return new JsonHierarchicalStreamDriver() {
	            public HierarchicalStreamWriter createWriter(Writer writer) {
	                  return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
	            }
	       };
	   }
}

[/quote]
se sua classe já está assim, vc não precisa implementar aquela interface… result.use(json()) deveria usar a sua implementação…

faz o seguinte, em algum ponto de sua lógica:

System.out.println(this.json == result.use(json()));
System.out.println(this.json.getClass() == result.use(json()).getClass());

tem que imprimir true nos dois casos, ou pelo menos no segundo.

se imprimir true, vc pode tirar o this.json da sua classe e usar o result.use(json()) no lugar. Vai funcionar direito

Lucas, imprimiu no console, true, true.

Agora como eu faço para consumir esse objeto?

Tenho no meu jsp esse codigo, mais não chega a dar um alert no json. Continua aparecendo o arquivo pra download.

[code]
$(function() {
var json = $.getJSON("<c:url value=’/cooperado.pesquisar’ />");

		alert(json); 
	});
</script>

[/code]

troca o
this.json.from(object).serialize()
para
result.use(json()).from(object).serialize()

isso eu ja fiz.

em que arquivo está esse código?

	<script type="text/javascript">
		$(function() {
		      var json = $.getJSON("<c:url value='/cooperado.pesquisar' />");

			alert(json); 
		});
	</script>

no pesquisar.jsp, o engraçado é o seguinte.

Esse jsp é uma tela de pesquisa em determinada situação e uma modal em outra situação, então eu tenho o mesmo jsp usando em dois lugar com a mesma finalidade.

Na tela onde eu utilizo esse jsp como modal o alert(json) aparece XMLHttpRequest, sendo assim eu consigo utilizar o objeto.
Já na situação em que esse jsp é uma tela normal de pesquisa, me aparece o arquivo pra download.

então o problema é o seguinte: se vc quer produzir json, vc não deve ter o jsp… ele nem chega a chamar o jsp…

a solução fácil pra isso é criar duas lógicas, uma que gera html (com jsp) e uma que gera o json

hum, entendi, vou testar aqui.

[quote=lucascs]então o problema é o seguinte: se vc quer produzir json, vc não deve ter o jsp… ele nem chega a chamar o jsp…

a solução fácil pra isso é criar duas lógicas, uma que gera html (com jsp) e uma que gera o json[/quote]

Nesse caso ele não pode usar o representation? Assim dependendo do accept ele faz jsp ou json.

representation? o que seria?

o representation não foi lançado ainda… vai estar no 3.0.3…

o representation funciona assim: vc faz

result.use(Results.representation()).from(objeto).serialize();

se vier o parâmetro _format=json na requisição, a resposta vai ser um json do objeto.
se vier o _format=xml, vai gerar um xml do objeto
se não vier nada ele vai pra jsp padrão (com o objeto adicionado, eu acho)

assim vc não precisa de duas lógicas… basta passar o parametro _format=json no $.getJSON(…)

se quiser o SNAPSHOT-3.0.3 pra usar isso:
http://www.linux.ime.usp.br/~lucascs/vraptor-3.0.3-SNAPSHOT.jar

[]'s

opa, tudo certo, até agora.

Valeu mesmo.

Essa versão do vraptor eu já estava usando, o Garcia tinha me mandado por email, mais de qualquer forma obrigado.

Representation leva em questão apenas o _format ou também os headers? No caso se meu accept for json ele considera?

[quote=lucascs]o representation não foi lançado ainda… vai estar no 3.0.3…

o representation funciona assim: vc faz

result.use(Results.representation()).from(objeto).serialize();

se vier o parâmetro _format=json na requisição, a resposta vai ser um json do objeto.
se vier o _format=xml, vai gerar um xml do objeto
se não vier nada ele vai pra jsp padrão (com o objeto adicionado, eu acho)

assim vc não precisa de duas lógicas… basta passar o parametro _format=json no $.getJSON(…)

se quiser o SNAPSHOT-3.0.3 pra usar isso:
http://www.linux.ime.usp.br/~lucascs/vraptor-3.0.3-SNAPSHOT.jar

[]'s[/quote]

leva em questão os headers tb… (o Accept)

mas via javascript é um pouco mais difícil setar headers, então usar o _format é mais prático

Como eu estou usando o jquery ui Dialog para fazer a modal, no submit da modal para fazer a pesquisa, esta sendo redirecionado para a página pesquisar.jsp.

Tem alguma forma de fazer o submit sem que saia da modal?
Ou vocês tem alguma outra sugestão de plugin para modal.