Nesse artigo, iremos implementar o recurso de Autocompletar em uma aplicação Spring MVC usando o JQuery. O Auto-completar é um recurso visto em quase todas as boas aplicações web. Ela permite que o usuário selecione os valores apropriados em uma lista de itens. A adiçao desse recurso é recomendável se o campo possuir múltiplos (> 20 a 25) valores.
Nossos requisitos são simples. Teremos dois campos Country e Technologies. Os dois campos terão o recurso de auto-completar de forma que o usuário seja capaz de selecionar valores em uma lista de países e tecnologias. O campo país terá apenas um valor, mas o campo tecnologia poderá ter múltiplos valores separados por virgula (,).
O que iremos precisar
Antes de começarmos nosso exemplo, precisaremos de algumas ferramentas.
- JDK 1.5 ou superior (download)
- Tomcat 5.x ou superior ou qualquer outro contêiner (Glassfish, JBoss, Websphere, Weblogic etc) (download)
- Eclipse 3.2.x ou superior (download)
- JQuery UI (Auto-completar) (download)
- Arquivos JAR do Spring 3.0 MVC: (download). A seguir uma lista dos arquivos JAR necessários para essa aplicação.
- jstl-1.2.jar
- org.springframework.asm-3.0.1.RELEASE-A.jar
- org.springframework.beans-3.0.1.RELEASE-A.jar
- org.springframework.context-3.0.1.RELEASE-A.jar
- org.springframework.core-3.0.1.RELEASE-A.jar
- org.springframework.expression-3.0.1.RELEASE-A.jar
- org.springframework.web.servlet-3.0.1.RELEASE-A.jar
- org.springframework.web-3.0.1.RELEASE-A.jar
- commons-logging-1.0.4.jar
- commons-beanutils-1.8.0.jar
- commons-digester-2.0.jar
- jackson-core-asl-1.9.7.jar
- jackson-mapper-asl-1.9.7.jar
Observe que dependendo da versão atual do Sptring MVC, os números de versão acima podem varias. Observe também que precisamos dos arquivos jackson mapper e jackson core. Esses arquivos são necessários para gerar arquivos JSON a partir de nosso controller Spring MVC.
Começando
vamos começar a desenvolver a nossa aplicação baseada no Spring 3.0 MVC. Abra o Eclipse e acesse File -> New -> Project selecionando Dynamic Web Project na tela que aparece.
Após selecionar Dynamic Web Project, pressione Next.
Escreve um nome para o projeto. Por exemplo, SpringMVC_Autocomplete. Após ter feito isso, selecione o ambiente alvo (ex.: Apache Tomcat v6.0). Isso é feito para poder rodar o projeto de dentro do ambiente Eclipse. Depois disso pressione Finish.
Uma vez que o projeto tenha sido criado, você pode visualizar sua estrutura no Project Explorer. Essa é a forma que o projeto deve parecer assim que tivermos finalizado o tutorial e adicionado todo o código fonte.
Agora copie todos os arquivos JAR necessáriso no diretório WebContent > WEB-INF > lib. Crie esse diretório caso não exista.
Um banco de dados de teste
Normalmente você precisará de um banco de dados de onde irá puxar os valores necessários para o Auto-completar. Mas por questões de simplicidade, criaremos uma classe java DummyDB.
Após o projeto ter sido criado, crie um pacote net.viralpatel.springmvc.autocomplete e um arquivo DummyDB.java. DummyDB.java é a classe que simulará a conexão com o banco de dados e fornecerá os dados para nosso exemplo.
Arquivo: /src/net/viralpatel/springmvc/autocomplete/DummyDB.java
package net.viralpatel.spring.autocomplete; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; public class DummyDB { private List<String> countries; private List<String> tags; public DummyDB() { String data = "Afghanistan, Albania, Algeria, Andorra, Angola, Antigua & Deps,"+ "United Kingdom,United States,Uruguay,Uzbekistan,Vanuatu,Vatican City,Venezuela,Vietnam,Yemen,Zambia,Zimbabwe"; countries = new ArrayList<String>(); StringTokenizer st = new StringTokenizer(data, ","); //Parse the country CSV list and set as Array while(st.hasMoreTokens()) { countries.add(st.nextToken().trim()); } String strTags = "SharePoint, Spring, Struts, Java, JQuery, ASP, PHP, JavaScript, MySQL, ASP, .NET"; tags = new ArrayList<String>(); StringTokenizer st2 = new StringTokenizer(strTags, ","); //Parse the tags CSV list and set as Array while(st2.hasMoreTokens()) { tags.add(st2.nextToken().trim()); } } public List<String> getCountryList(String query) { String country = null; query = query.toLowerCase(); List<String> matched = new ArrayList<String>(); for(int i=0; i < countries.size(); i++) { country = countries.get(i).toLowerCase(); if(country.startsWith(query)) { matched.add(countries.get(i)); } } return matched; } public List<String> getTechList(String query) { String country = null; query = query.toLowerCase(); List<String> matched = new ArrayList<String>(); for(int i=0; i < tags.size(); i++) { country = tags.get(i).toLowerCase(); if(country.startsWith(query)) { matched.add(tags.get(i)); } } return matched; } } |
O DummyDB.java
contém a lista de todos os países e tecnologias em uma String separados por vírgulas e métodos getCountryList()
e getTechList()
que retornarão uma lista de países e tecnologias que começem com a String passada como argumento. Dessa forma se passarmos “IN” a esse método, ele retornará todos os países começados por IN.
Você pode alterar esse código para adicionar a implementação orientada a acessar o banco de dados. Apenas um simples "SELECT * FROM <table> WHERE country LIKE " query
irá servir aos propósitos da aplicação.
Agora criaremos o controller do SpringMVC que retornará uma saída JSON para o Auto-completar.
O Controller do Spring MVC
A classe do controller do Spring MVC irá processar a requisição e retorna uma saída JSON. Para isso crie uma classe UserController.java
sob o pacote net.viralpatel.springmvc.autocomplete
.
package net.viralpatel.spring.autocomplete; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; @Controller public class UserController { private static DummyDB dummyDB = new DummyDB(); @RequestMapping(value = "/index", method = RequestMethod.GET) public ModelAndView index() { User userForm = new User(); return new ModelAndView("user", "userForm", userForm); } @RequestMapping(value = "/get_country_list", method = RequestMethod.GET, headers="Accept=*/*") public @ResponseBody List<String> getCountryList(@RequestParam("term") String query) { List<String> countryList = dummyDB.getCountryList(query); return countryList; } @RequestMapping(value = "/get_tech_list", method = RequestMethod.GET, headers="Accept=*/*") public @ResponseBody List<String> getTechList(@RequestParam("term") String query) { List<String> countryList = dummyDB.getTechList(query); return countryList; } } |
Agora usaremos a anotação @ResponseBody
dos métodos getCountryList()
egetTechList()
. O Spring MVC converte o retorno dos métodos que em nosso caso é List em dados JSON.
A seguir o contéudo do arquivo spring-servlet.xml.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="net.viralpatel.spring.autocomplete" /> <mvc:annotation-driven /> <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> </beans> |
A tag é necessária aqui. Isso permite que o Spring processe anotações como @ResponseBody
.
A classe User.java abaixo é necessária apenas para ligar um formulário com o JSP. No nosso exemplo, ela não é necessária. Mas para o bom uso do Spring MVC iremos adiciona-la.
Arquivo: /src/net/viralpatel/springmvc/autocomplete/User.java
package net.viralpatel.spring.autocomplete; public class User { private String name; private String country; private String technologies; //Getter and Setter methods } |
O View JSP
Agora adicionaremos o arquivo JSP que irá renderizar o formulário User. Iremos adicionar também um index.jsp que irá redirecionar para a requisição apropriada.
Arquivo: /WebContent/index.jsp
<jsp:forward page="index.html"></jsp:forward> |
Arquivo: /WebContent/WEB-INF/jsp/user.jsp
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Spring MVC Autocomplete with JQuery & JSON example</title> <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script> </head> <body> <h2>Spring MVC Autocomplete with JQuery & JSON example</h2> <form:form method="post" action="save.html" modelAttribute="userForm"> <table> <tr> <th>Name</th> <td><form:input path="name" /></td> </tr> <tr> <th>Country</th> <td><form:input path="country" id="country" /></td> </tr> <tr> <th>Technologies</th> <td><form:input path="technologies" id="technologies" /></td> </tr> <tr> <td colspan="2"> <input type="submit" value="Save" /> <input type="reset" value="Reset" /> </td> </tr> </table> <br /> </form:form> <script type="text/javascript"> function split(val) { return val.split(/,\s*/); } function extractLast(term) { return split(term).pop(); } $(document).ready(function() { $( "#country" ).autocomplete({ source: '${pageContext. request. contextPath}/get_country_list.html' }); $( "#technologies").autocomplete({ source: function (request, response) { $.getJSON("${pageContext. request. contextPath}/get_tech_list.html", { term: extractLast(request.term) }, response); }, search: function () { // custom minLength var term = extractLast(this.value); if (term.length < 1) { return false; } }, focus: function () { // prevent value inserted on focus return false; }, select: function (event, ui) { var terms = split(this.value); // remove the current input terms.pop(); // add the selected item terms.push(ui.item.value); // add placeholder to get the comma-and-space at the end terms.push(""); this.value = terms.join(", "); return false; } }); }); </script> </body> </html> |
Verifique o arquivo JSP acima. Adicionamos campos INPUT para Country e tecnology. Também usamos$().autocomplete()
para ativar o recurso de auto-completar. Para o país o uso é bem direto: $( "#country" ).autocomplete()
mas para tecnologias fizemos alguns processamentos e divisões na entrada. Isso se deve ao fato de que podemos ter múltiplos valores para o campo, separados por vírgula.
Isso é tudo pessoal
Você pode agora executar a aplicação para visualizar o resultado. Aqui, assume-se que você já configurou o Tomcat no Eclipse. Tudo que precisa fazer é:
Abra a aba Server em Windows > Show View > Server. Clique com o botão direito do mouse nessa área e selecione New > Server para adicionar os detalhes do servidor.
Para executar o projeto, clique com o botão direito no nome do projeto e selecione Run as > Run on Server (Shortcut: Alt+Shift+X, R)
Baixar o código fonte
SpringMVC_Autocomplete.zip (4.2 MB)
Traduzido de viralpatel.net