[RESOLVIDO]VRaptor com autocomplete

13 respostas
donny

Estou com dificuldade para pegar a resposta de uma requisição via JSON feita pelo autocomplete. A chamada e a resposta são feitas com sucesso, o meu problema é o processamento da resposta.
Estou usando o VRaptor: vraptor-3.1.2-20100214.025052-1.jar.

Segue abaixo o código do controller:

@Get
	@Path("/viagem/autocomplete.json")
	public void autoComplete(String name_startsWith) {
		System.out.println("AutoCompletar");
		List<Cliente> lista = clienteService.buscar(name_startsWith);
		result.use(Results.json()).from(lista).serialize(); //Nessa versão do VRaptor NÃO tem o método >>>.withoutRoot()<<<.
	}

Código javaScript:

<script>
	$(function() {
		$( "#txtCliente" ).autocomplete({
			source: function( request, response ) {
				$.ajax({
					url: "<c:url value='/viagem/autocomplete.json'/>",
					dataType: "json",
					data: {
						featureClass: "P",
						style: "full",
						maxRows: 12,
						name_startsWith: request.term
					},
					success: function( data ) {
						response( $.map( data, function( item ) {
							return {
								label: item.nome, //Aqui está errado como estou pegando a resposta
								value: item.nome, //Aqui está errado como estou pegando a resposta
								id: item.id  //Aqui está errado como estou pegando a resposta
							}
						}));
					}
				});
			},
			minLength: 2,
			select: function(event, ui ) {
				//alert("select" + ui.item.id); //Aqui está errado como estou pegando a resposta
				$('#idCliente').val(ui.item.id);  //Aqui está errado como estou pegando a resposta
			},
			open: function() {
				$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
			},
			close: function() {
				$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
			}
		});

	});
</script>

Abaixo o código da resposta:

{"list": [
  [
    421,
    "ASA AGRO INDUSTRIAL DE ALIMENTOS S A"
  ],
  [
    8802,
    "ASA BRANCA DO APOLLO MERCEARIA LTDA"
  ],
  [
    9626,
    "ASA BRANCA DO APOLLO MERCEARIA LTDA"
  ],
  [
    9496,
    "ASA BRANCA INDL. COML. E IMPORTADORA LTDA"
  ],
  [
    14086,
    "ASA BRANCA INDL. COML. E IMPORTADORA LTDA"
  ],
  [
    15121,
    "ASFRAN - COMERCIAL DE ALIMENTOS LTDA."
  ],
  [
    15481,
    "ASSIS & ASSIS SUPERMERCADO LTDA"
  ],
  [
    13131,
    "ASSOCIACAO DOS SERVIDORES DA PREFEITURA M DE COLOMBO"
  ],
  [
    403,
    "ASTOR NERE DE SOUZA ME"
  ],
  [
    12092,
    "ASTRONAUTA DISTRIBUIDORA DE ALIMENTOS LTDA"
  ],
  [
    14518,
    "ASUN COM GEN ALIM LTDA"
  ]
]}

Na tela o plugin autocomplete apresenta apenas um item como resultado, especificado como “UNDEFINED”.

13 Respostas

Rafael_Guerreiro

Eu não sei se essa solução funciona, mas não custa tentar:

success: function( data ) {  
//Ao invés de data, passa data.list
                        response( $.map( data.list, function( item ) {  
                            return {  
                                label: item.nome, 
                                value: item.nome,
                                id: item.id  
                            }  
                        }));  
                    }

Mas para que você pudesse pegar o atributo nome ou id, seu JSON deveria estar assim:

{"list": [  
  [  
    "id": 421,  
    "nome": "ASA AGRO INDUSTRIAL DE ALIMENTOS S A"  
  ]
]}
donny

Também não entendo pq não vem as “chaves” nome e id junto. Imagino que isso deve ser especificado no result.use(), certo?

donny

Um avanço! O código abaixo pega apenas a primeira posição:

success: function( data ) {
						response( $.map( data, function( item ) {
							return {
								label: item[0][1],//O "0" aqui teria que ser uma variável e incrementada em cada loop.
								value: item[0][1],
								id: item[0][0]  
							}
						}));
					}

Como eu poderia substituir o “0” do primeiro colchetes por uma variável auto incrementável?

Rafael_Guerreiro

Existe um “workarround”:
Seu método retorna a lista normal.

@Get  
@Path("/viagem/autocomplete.json")  
public List<Cliente> autoComplete(String name_startsWith) {  
    System.out.println("AutoCompletar");  
    return clienteService.buscar(name_startsWith);
}

Ai você cria uma jsp com o nome de autoComplete.json.jsp (repara que precisa ter o .json)

{
<c:forEach items="${clienteList}" var="cliente" varStatus="status">
[    
    "id": ${cliente.id},    
    "nome": "${cliente.nome}"    
  ]
<c:if test="${not status.last}">
,
</c:if>
</c:forEach>
}
donny

Criei um novo JSP na mesma pasta que o outro JSP:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
{
<c:forEach items="${clienteList}" var="cliente" varStatus="status">
[    
    "id": ${cliente.id},    
    "nome": "${cliente.nome}"    
  ]
<c:if test="${not status.last}">
,
</c:if>
</c:forEach>
}

Usamos o Tiles, ocorreu a seguinte exception:

23/05/2012 11:06:17 org.apache.catalina.core.ApplicationDispatcher invoke
GRAVE: Servlet.service() for servlet TilesDispatchServlet threw exception
org.apache.tiles.definition.NoSuchDefinitionException: viagem.autocomplete
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:624)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:322)
	at org.apache.tiles.web.util.TilesDispatchServlet.doGet(TilesDispatchServlet.java:99)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
	at br.com.caelum.vraptor.view.DefaultPageResult.forward(DefaultPageResult.java:67)
	at br.com.caelum.vraptor.extra.ForwardToDefaultViewInterceptor.intercept(ForwardToDefaultViewInterceptor.java:59)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.OutjectResult.intercept(OutjectResult.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:75)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.rkam.clog.interceptor.NoCacheInterceptor.intercept(NoCacheInterceptor.java:38)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at br.com.rkam.clog.outros.DisableUrlSessionFilter.doFilter(DisableUrlSessionFilter.java:59)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Unknown Source)
23/05/2012 11:06:17 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet default threw exception
org.apache.tiles.definition.NoSuchDefinitionException: viagem.autocomplete
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:624)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:322)
	at org.apache.tiles.web.util.TilesDispatchServlet.doGet(TilesDispatchServlet.java:99)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
	at br.com.caelum.vraptor.view.DefaultPageResult.forward(DefaultPageResult.java:67)
	at br.com.caelum.vraptor.extra.ForwardToDefaultViewInterceptor.intercept(ForwardToDefaultViewInterceptor.java:59)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.OutjectResult.intercept(OutjectResult.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:75)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.rkam.clog.interceptor.NoCacheInterceptor.intercept(NoCacheInterceptor.java:38)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at br.com.rkam.clog.outros.DisableUrlSessionFilter.doFilter(DisableUrlSessionFilter.java:59)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Unknown Source)
Rafael_Guerreiro

Ix. Nunca mexi com Tiles…

Mas você colocou .json no nome da jsp?

você fez o método retornar a lista?

donny

O nome do JSP ficou: autoComplete.json.jsp

Tive uma ideia, vou voltar a forma antiga, vou pegar a lista e montar uma String com o formato que o JSP que você passou faz, ou seja, tirar esse trabalho do JSP e fazer no Controller. O que você acha Rafael?

donny

O método no controller ficou assim:

@Get
	@Path("/viagem/autocomplete.json")
	public void autoComplete(String name_startsWith) {
		System.out.println("AutoCompletar");
		List<Cliente> lista = clienteService.buscar(name_startsWith);
		StringBuilder ret = null;
		if(lista!=null && lista.size()>0){
			ret = new StringBuilder();
			ret.append("{[");
			String virgula = "";
			for(Cliente c : lista){
				ret.append(virgula);
				ret.append("'id':" + c.getId());
				ret.append("'nome':" + c.getNome()+"]");
				virgula = ",";
			}
			ret.append("}");
		}
		result.use(Results.json()).from(ret.toString()).serialize();
	}
Rafael_Guerreiro

Toma cuidado para não colocar vírgula no último registro.

Depois de montar a String, pega o lastIndexOf(","); e arranca esse cara fora (se não o json fica errado e não funciona)

Olha cara, eu realmente não sei. Se dessa forma não funcionar, tenta retornar a String para a mesma json.jsp mas lá fica só assim ${string}.

Como que funciona o tiles? ele coloca o cabeçalho e o caminho de pão automaticamente?

–EDIT

Esquece o q eu falei da virgula, está certo isso ai.

donny

Tiles cuida da parte da montagem das páginas, cabeçalho…

Agora está funcionando o retorno como deve ser:

{"list": [
  {
    "id": 421,
    "nome": "ASA AGRO INDUSTRIAL DE ALIMENTOS S A"
  },
  {
    "id": 8802,
    "nome": "ASA BRANCA DO APOLLO MERCEARIA LTDA"
  },
  {
    "id": 9626,
    "nome": "ASA BRANCA DO APOLLO MERCEARIA LTDA"
  },
  {
    "id": 14086,
    "nome": "ASA BRANCA INDL. COML. E IMPORTADORA LTDA"
  },
  {
    "id": 9496,
    "nome": "ASA BRANCA INDL. COML. E IMPORTADORA LTDA"
  },
  {
    "id": 15121,
    "nome": "ASFRAN - COMERCIAL DE ALIMENTOS LTDA."
  },
  {
    "id": 15481,
    "nome": "ASSIS & ASSIS SUPERMERCADO LTDA"
  },
  {
    "id": 13131,
    "nome": "ASSOCIACAO DOS SERVIDORES DA PREFEITURA M DE COLOMBO"
  },
  {
    "id": 403,
    "nome": "ASTOR NERE DE SOUZA ME"
  },
  {
    "id": 12092,
    "nome": "ASTRONAUTA DISTRIBUIDORA DE ALIMENTOS LTDA"
  },
  {
    "id": 14518,
    "nome": "ASUN COM GEN ALIM LTDA"
  }
]}

Porém no autocomplete segue mostrando apenas um item como UNDEFINED.

Rafael_Guerreiro

É por causa do list…

Você tentou passar o data.list para o return?

donny

Era isso mesmo! Muito obrigado pela ajuda Rafael. Está funcionando perfeito.

Rafael_Guerreiro

Já que você está usando o Serialize do VRaptor, você não precisa mais da json.jsp… Você apagou ela?

Legal que funcionou. Infelizmente não da melhor forma…

Criado 23 de maio de 2012
Ultima resposta 23 de mai. de 2012
Respostas 13
Participantes 2