VRaptor + JQuery + JSON = Erro

43 respostas
fabioebner

Amigos, estou com problema, fiz um autocomplete em JQuery que acessa uma url o vraptor faz uma verificacao e retorna um objeto (que vira json) para o Jquery, porem agora eu estou tentando passar esse JSON do js para outro metodo do vraptor e nao estou conseguindo.

alguem pode me dar um help??

valeu

43 Respostas

fabioebner

Não sei se tem alguma coisa mas o meu objeto java e o seguinte:

package com.noname.entity;

import org.bson.types.ObjectId;

import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Id;
import com.google.code.morphia.annotations.Indexed;
import com.google.code.morphia.utils.IndexDirection;

@Entity("product")
public class Product {

	@Id
	private ObjectId	cdProduct;
	@Indexed(value = IndexDirection.ASC, name="nmProductIndex")
	private String nmProduct;
	
	public ObjectId getCdProduct() {
		return cdProduct;
	}
	public void setCdProduct(ObjectId cdProduct) {
		this.cdProduct = cdProduct;
	}
	public String getNmProduct() {
		return nmProduct;
	}
	public void setNmProduct(String nmProduct) {
		this.nmProduct = nmProduct;
	}
	
	
	
}

o meu metodo e o seguinte que retorna para o autocomplete e o seguinte:

@Post
	@Get
	@Path("/product/getProduct")
	public void getProduct(String nmProduct) throws Exception{
		abreConexao();
		List<Product> productList = ds.createQuery(Product.class).field("nmProduct").containsIgnoreCase(nmProduct).asList();
		result.use(json()).from(productList, "productList").include("cdProduct").serialize();
	}

Segue o metodo do autocomplete:

$(function() {
	function log( message ) {
		$( "<div/>" ).text( message ).prependTo( "#log" );
		$( "#log" ).scrollTop( 0 );
	}

	$( "#product" ).autocomplete({
		source: function( request, response ) {
			$.ajax({
				url: "http://localhost:8080/noname/product/getProduct",
				type: "post",
				dataType: "json",
				data: {
					nmProduct: request.term
				},
				success:
					function( data ) {
					response( $.map( data.productList, function( item ) {
						return {
							label: item.cdProduct._time,//name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
							value: item
						};
 					}));
				}
			});
		},
		minLength: 2,
		select: function( event, ui ) {
			product = ui.item.value; //aqui eu jogo o ui.item.value dentro de uma variavel criada fora da funcion var product = null;
			
			log( ui.item ?
				"Selected: " + ui.item.label :
				"Nothing selected, input was " + this.value);
		},
		open: function() {
			$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
		},
		close: function() {
			$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
		}
	});
});

o meu retorno e o seguinte:

porem eu vi uma coisa estranha, eu estava debugando o JS e percebi que ele coloca o no final do objeto um tal de _proto conforme a imagem abaixo, dai qdo eu vou mandar esse objeto para o meu metodo ele nao chega…

Lucas_Cavalcanti

onde vc tá tentando passar o json pro controller?

esse proto é uma variável interna dos objetos javascript.

fabioebner

ja tentei de todas as formas, essa e uma:

$.ajax({
		type: "post",
		data: product,
		dataType: "json",
    	  url: 'http://localhost:8080/noname/productStore/addProductStore',
    	  success: function(data) {
    	    $('.result').html(data);
    	    alert('Load was performed.');
    	  }
    	});
Lucas_Cavalcanti

vc precisa passar o produto inteiro mesmo?

vc não pode passar só o id dele, e recarregá-lo no controller?

daí vc pode fazer:

...
data: {"product.id": product.id},
....
fabioebner

Entao e pq o mongodb entao o id nao e um id simples, ehheheh e ja tentei colocar para receber ObjectID mas tbm da erro :frowning:

fabioebner

Se liga, eu conseguiria passar isso se fosse via form do jsp? eu recupero pelo Autocomplete do JQUERY mas na hora de retornar para o meu servidor eu mando Os OBJETOS via form do jsp??

se sim, vc te um exemplo??

obrigado

fabioebner

ou quem sabe fazer via XML, fica mais facil?? o js tbm vai add coisa no xml para qdo eu voltar dar erro??

Lucas_Cavalcanti

vamos lá… o que vc tá usando pra criar o seu objectId?

uma string ou um outro objeto?

a idéia é vc tentar passar pro controller o objeto dentro do objectId, e criar o objectId no servidor, ou criar um converter pra object id…

fabioebner

Entao eu so criei o ObjectId com o @Id do morphia la, e nao seto nada nele, ele auto cria o id

Lucas_Cavalcanti

se vc não fosse usar web, como vc faria pra buscar o objeto no mongo?

vc não tem como controlar algum valor desse id?

fabioebner

Entao cara eu nao conheco mto o mongo estou comecando a mexer agora, mas o ID dele eu crio como OBjectID, logo se eu quiser buscar pelo ID tenho que passar o objeto inteiro eu acho…

se nao fosse usar na web eu tenho o objeto e busco por ele, mas como e um objeto com algumas propriedades estou com problema na hora de passr como json do JScript para o vraptor.

Lucas_Cavalcanti

o vraptor consegue consumir json, só colocar @Consumes no método, o problema é fazer o jquery fazer isso…

fabioebner

Lucas, eu coloquei o @Consumes no metodo, e agora qdo eu chamo o ajax ele nem para o metodo, se eu tirar o consumes ele para no metodo mas nao chega nada.

fabioebner

Lucas, e aquela ideia que eu comentei de usar o autocomplete para recuperar o meu produto, dai fazer o JS passar para o meu form java (jsp) e via post do formulario via JSP eu mando o objeto de volta para o back…

sabe se e possivel?? se sim… tem algum exemplo?

vlw

Lucas_Cavalcanti

ainda vai cair no mesmo problema de vc não conseguir criar um ObjectId pra buscar um cara do banco.

do jeito que eu usei o mongo, eu fazia algo do tipo:

ObjectId id = new ObjectId("4f4fb323344878abced");

tanto pra salvar qto pra recuperar… funcionava bem.

fabioebner

Cara ta quase chegando la, o problema e que eu retorno o objeto para o JS, e como eu pego esse valor no JS?? hehehe no java e so eu dar um print do toString que vai, mais no javascript nao… e eu faze um loop na lista so para colocar esse valor para passar pro JS e complicado ne… tem como eu recuperar esse codigo no js?

Lucas_Cavalcanti

pra retornar o objeto pro js, vc pode fazer pelo json mesmo…

result.use(json()).from(id, "id").serialize();

daí vc consegue fazer usando o JQuery:

$.getJSON("....url...", function(json) {
     var id = json.id;

     alert(id);
}
fabioebner

Entao pra mim ele imprime no JS [object object]

Lucas_Cavalcanti

então veio algo :wink:

use um browser decente (tipo o firefox com firebug ou chrome) e faça console.log(id)… vai aparecer no console do firebug ou do chrome (F12 abre o console geralmente)

assim vai aparecer os dados. se não aparecer tenta console.dir(id)

fabioebner

Entao ele mostra o que esta na imagem abaixo, o problema e que eu nao consigo voltar isso ai para o server, e nao consigo pegar o id (4fba6e29701675f9306bd4f3) do objeto


Lucas_Cavalcanti

Esse ObjectId tem getters e setters?

se sim, tenta usar o nome dos setters pra popular o objectId no servidor:

var id = // o objectId que veio

var data = {
     "id.inc": id._inc,
     "id.machine": id._machine,
     "id.new": id._new,
     "id.time": id._time
 };

$.post("....url....", data, function() {
   //...
});

e receba um ObjectId id no método do controller.

só que pra isso funcionar precisa ter os setters (setInc, setMachine, etc)

fabioebner

Cara. eu pensei em fazer isso, mas o problema e que eu recebo: 5 objetos sendo q 1 e uma lista. vou ter que fazer 5x4 + Nx4, impossivel heeheheheh por isso tinha pensando em recuperar o JSon via JS e colocar no meu form, pq dai com um form Jsp eu dou um post enviando isso e recebo correto?

fabioebner

Perai, acho que eu entendi, errado, vc esta falando para eu criar o Json no JS?? e nao repassar o objeto que eu recebi do meu java, eu recebo o objeto, crio o json com os Getters e Setters e passo esse novo objeto para o meu metodo… correto?

Lucas_Cavalcanti

Fabio, o objeto java NUNCA vai pro javascript. O que vai é alguma representação dele, seja string, seja json, seja o que for.

pra passar para o servidor vc vai precisar usar alguma representação que o servidor saiba transformar em objeto de novo. Por exemplo json, ou form parameters.

fabioebner

eu sei… o que tentei falar e que o vraptor passa um JSON para o meu JS, mas eu nao consigo pegar esse JSON gerado pelo VRAPTOR e via javascript retornar ele para o JAVA, ele nao chega no meu metodo java. vou tentar fazer dessa forma que vc falou… vamos ver o que vai dar

fabioebner

Tentei fazer o seguinte:

$.ajax({
		type: "post",
		data: produto = {  
			     "id.inc": product.cdProduct._inc,  
			     "id.machine": product.cdProduct._machine,  
			     "id.new": product.cdProduct._new,  
			     "id.time": product.cdProduct._time  
			},
		dataType: "json",
    	  url: 'http://localhost:8080/noname/productStore/addProductStores',
    	  success: function(data) {
    	    $('.result').html(data);
    	    alert('Load was performed.');
    	  }
    	});

e o metodo

@Post
	@Get
	@Path("productStore/addProductStores")
	public void addProductStores(ObjectId produto) throws Exception{
		abrirConexao();
	
	}

e recebi o seguinte erro:

Lucas_Cavalcanti

então… é pq qdo vc usa o post do jquery e passa um objeto javascript (json) ele não passa esse objeto, ele tenta serializar pra form parameters e fica zoadão… se vc quer passar o objeto por json vc precisa mudar o content-type do post pra json, e mandar ele serializar o json mesmo… tem uma opção pra isso se eu não me engano.

Lucas_Cavalcanti

vixe… desse jeito não vai rolar mesmo… ele tenta ler os nomes dos parâmetros do ObjectID, e como ele não foi compilado com informação de debug, não dá…

talvez vc tenha que implementar isso com um converter pra ObjectID mesmo…

fabioebner

entao, nao e o dataType: "json" ??

fabioebner

e existe uma forma facil de fazer converter??? tem anotacao e coisas do genero?

valeu

fabioebner

e lucas, eu nao consigo qdo receber o Json pelo JS passar ele para form parameter? pq dai via form parameter eu consigo passar o objeto inteiro para o vraptor nao e?

Lucas_Cavalcanti

pra receber um json, não pra enviar :wink:

fabioebner

resumindo… me ferrei ne? ahahahhahahahaahahh

Lucas_Cavalcanti

quase isso :wink:

http://api.jquery.com/jQuery.ajax/

brinca aí com as options possíveis…
tipo a contentType e a data mandando como string

Lucas_Cavalcanti

o processData tb eh bom

fabioebner

sim sim… entao eu recebo um JSON e jogo ele no meu form… entendeu?? eu tenho la no meu JSP o meu form, com os objetos que eu quero enviar para o BACK, dai eu faco um autocomplete, recebo via JSON do meu Vraptor, o objeto que eu quero, e na minha funcao javascript, eu seto as variaveis do meu form com o retorno

entendeu +/- a jogada?

Lucas_Cavalcanti

E assim funciona?

se vc colocar o json como uma string no form, vc vai ter que deserializar na mão no lado do servidor…

daí vc consegue fazer um converter pra ObjectId

fabioebner

bom vou tentar alguma coisa aqui… se bobiar vou criar um String dentro do meu objeto e antes de voltar parao JS eu loop a colecao e coloco o ID nesse campo, para retornar para o java depois

so tira uma ultima duvida, e possivel eu enviar no ajax mais de 1 parametro nao e? tu sabe como

valeu

fabioebner

Lucas, tira uma duvida, vc falou que ja mexeu com MongoDb…

tem mta diferenca de performance, entre eu fazer uma busca pelo @Id ObjectID Id;

tipo:

ObjectID id = new ObjectID("ff23f2ff");
 ds.get(Product.class, id);

ou buscar por um campo String

ds.find(Product.class).field("nmProduct").equals("shampoo");

pq se nao tiver eu faco a busca pelo nome mesmo (sempre vou ter apenas 1 produto com auqele nome)
???

Lucas_Cavalcanti

se vc consegue buscar por nome, faça isso então, ao invés de passar o objectid…

daí vc passa só um ?nome=nomeDoCara na requisição que já era.

fabioebner

E o que eu vou tentar fazer … e se liga, tu sabe como enviar mais de 1 parametro no ajax?? tem um exemplo ai? valeu

Lucas_Cavalcanti

sim, só usar o data:

$.ajax( {
   //...
   data: {
      param1: ....,
      param2: ...,
      param3:....
   }

});
A

da forma que voce esta fazendo, nao vai chegar “produto” no controler, o que vai chega é “id” com os parametros que voce colocou.
Esse "produto = " não tá servindo de nada. Só você ver: var e = {w: prod = {a:1}}; console.log(JSON.stringify(e));

O resultado é: “{“w”:{“a”:1}}”, onde está o "prod = "? :slight_smile:
Se eu digitar console.log(prod), ele está lá, porém isso não está sendo enviado pelo ajax. Se voce quer receber produto lá, deveria colocar produto.id.inc, produto.id.machine, …

fabioebner:
Tentei fazer o seguinte:

$.ajax({
		type: "post",
		data: produto = {  
			     "id.inc": product.cdProduct._inc,  
			     "id.machine": product.cdProduct._machine,  
			     "id.new": product.cdProduct._new,  
			     "id.time": product.cdProduct._time  
			},
		dataType: "json",
    	  url: 'http://localhost:8080/noname/productStore/addProductStores',
    	  success: function(data) {
    	    $('.result').html(data);
    	    alert('Load was performed.');
    	  }
    	});

e o metodo

@Post
	@Get
	@Path("productStore/addProductStores")
	public void addProductStores(ObjectId produto) throws Exception{
		abrirConexao();
	
	}

e recebi o seguinte erro:

<blockquote>

GRAVE: Servlet.service() for servlet [default] in context with path [/noname] threw exception

br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target(name=produto, type=class org.bson.types.ObjectId)

at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:95)

at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:87)

at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:80)

at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateOrAddError(IogiParametersProvider.java:80)

at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateParameters(IogiParametersProvider.java:73)

at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.getParametersFor(IogiParametersProvider.java:63)

at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:126)

at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:83)

at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)

at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)

at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)

at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)

at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)

at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)

at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)

at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)

at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)

at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)

at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)

at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)

at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)

at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)

at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)

at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)

at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)

at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91)

at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)

at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:88)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)

at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)

at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)

at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

Caused by: java.lang.IllegalStateException: Paranamer were not able to find your parameter names for public org.bson.types.ObjectId(byte[])You must compile your code with debug information (javac -g) or register another name provider. Try to use br.com.caelum.vraptor.http.DefaultParameterNameProvider instead.

at br.com.caelum.vraptor.http.ParanamerNameProvider.parameterNamesFor(ParanamerNameProvider.java:60)

at br.com.caelum.vraptor.http.iogi.VRaptorParameterNamesProvider.lookupParameterNames(VRaptorParameterNamesProvider.java:29)

at br.com.caelum.iogi.reflection.ClassConstructor.(ClassConstructor.java:24)

at br.com.caelum.iogi.reflection.Target.constructors(Target.java:114)

at br.com.caelum.iogi.ObjectInstantiator.instantiate(ObjectInstantiator.java:30)

at br.com.caelum.iogi.MultiInstantiator.instantiate(MultiInstantiator.java:20)

at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:85)

 42 more

</blockquote></blockquote>
Criado 18 de maio de 2012
Ultima resposta 26 de ago. de 2013
Respostas 43
Participantes 3