VRaptor + JQuery + JSON = Erro

43 respostas
F

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

F

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…

L

onde vc tá tentando passar o json pro controller?

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

F

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.');
    	  }
    	});
L

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},
....
F

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:

F

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

F

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

L

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…

F

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

L

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?

F

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.

L

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

F

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.

F

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

L

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.

F

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?

L

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);
}
F

Entao pra mim ele imprime no JS [object object]

L

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)

F

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


L

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)

F

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?

F

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?

L

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.

F

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

F

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:

L

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.

L

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…

F

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

F

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

valeu

F

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?

L

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

F

resumindo… me ferrei ne? ahahahhahahahaahahh

L

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

L

o processData tb eh bom

F

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?

L

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

F

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

F

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)
???

L

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.

F

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

L

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