Let us implement Autocomplete feature in Spring MVC application using JQuery. Autocomplete is a feature you”ll see in almost all good web apps. It allows user to select proper values from a list of items. Adding this feature is recommended if the field has multiple ( > 20 to 25) values.
Related:Autocomplete in Java / JSP
Our requirement is simple. We will have two fields Country and Technologies. Both these fields will have autocomplete feature so user will be able to select from list of countries and technologies. The country field can have only one value. But the technologies field can have multiple values separated by comma (,).
Things We Need
Before we starts with our Spring MVC Autocomplete Example, we will need few tools.
- JDK 1.5 above (download)
- Tomcat 5.x above or any other container (Glassfish, JBoss, Websphere, Weblogic etc) (download)
- Eclipse 3.2.x above (download)
- JQuery UI (Autocomplete) (download)
- Spring 3.0 MVC JAR files:(download). Following are the list of JAR files required for this application.
- 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
Note that depending on the current version of Spring MVC, the version number of above jar files may change. Also note that we need jackson mapper and jackson core jars. This is required for generating JSON from our Spring MVC Controller.
Getting Started
Let us start with our Spring 3.0 MVC based application. Open Eclipse and goto File -> New -> Project and select Dynamic Web Project in the New Project wizard screen.
After selecting Dynamic Web Project, press Next.
Write the name of the project. For example SpringMVC_Autocomplete. Once this is done, select the target runtime environment (e.g. Apache Tomcat v6.0). This is to run the project inside Eclipse environment. After this press Finish. Once the project is created, you can see its structure in Project Explorer. This is how the project structure would look like once we finish the tutorial and add all source code.
Now copy all the required JAR files in WebContent > WEB-INF > lib folder. Create this folder if it does not exists.
The Dummy Database
Normally you would need a database from where you’ll fetch values required for autocomplete. But for sake of simplicity of this example we will write a DummyDB java class. Once the project is created, create a package net.viralpatel.springmvc.autocomplete and a Java class file DummyDB.java. DummyDB.java is the class that will simulate the database connection and it will provide the data for our example.
File: /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;
}
}
Code language: Java (java)
The DummyDB.java
contains the list of all the countries and technologies in a comma separated string value and a method getCountryList()
and getTechList()
that will return the list of countries and technologies starting with the string query passed as argument to that method. Thus if we pass “IN” to this method, it will return as all the countries starting with IN. You may want to change this code and add the database implementation here. Just a simple "SELECT * FROM <table> WHERE country LIKE " query
will serve the purpose. Now we write SpringMVC Controller that returns JSON output for Autocomplete.
The Spring MVC Controller
The spring mvc controller class that will process the request and returns JSON output. For this create a class UserController.java
under package net.viralpatel.springmvc.autocomplete
.
UserController.java
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;
}
}
Code language: Java (java)
Note how we used @ResponseBody
annotation in methods getCountryList()
and getTechList()
. Spring MVC converts the return type which in our case is List into JSON data. Following is the content of spring-servlet.xml file.
File: /WebContent/WEB-INF/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>
Code language: HTML, XML (xml)
The tag is required here. This lets Spring to process annotations like @ResponseBody
. The below User.java class is required only to bind a form with JSP. It is not required for this example. But for sake of Spring MVC we are using it.
File: /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
}
Code language: Java (java)
The JSP View
Now add JSP file which renders User form. Also we will add index.jsp which redirect to proper request.
File: /WebContent/index.jsp
<jsp:forward page="index.html"></jsp:forward>
Code language: HTML, XML (xml)
File: /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>
Code language: HTML, XML (xml)
Check the above JSP. We have added INPUT fields for Country and Technologies. Also we used $().autocomplete()
to enable autocomplete. For country it was straightforward $( "#country" ).autocomplete()
but for technologies we did some parsing and splitting. This is because we need multiple technologies in textbox separated by comma.
That’s All Folks
You may want to run the application see the result. I assume you have already configured Tomcat in eclipse. All you need to do: Open Server view from Windows > Show View > Server. Right click in this view and select New > Server and add your server details. To run the project, right click on Project name from Project Explorer and select Run as > Run on Server (Shortcut: Alt+Shift+X, R)
Download Source Code
SpringMVC_Autocomplete.zip (4.2 MB)
Great job. Only I have one slight problem. Not wanting to use JQuery UI just for one widget, and really don’t like JQuery UI. How can you use all the same code as you have, but a different AutoComplete widget?
Appreciate it. good example
Thanks
i had a doubt in the count text box you are showing the list countries starts with ” i ” but in the string data doesn’t have those name which starts with ” i “
see carefully the DummyDB.java file…String data contains all the country names and it also contains names starting with ‘i’….
Good stuff.
Good one.
Good example and works.
Only comment is, the jackson jar’s that is in the example screen needed to be updated with two more jar files that was is in the zip file.
Hi Satish,
I am getting json back.. But the not getting the dropdown… Can it be bcoz of those remaining 2 jar files?
That correct nilesh you need to add 2 jar that are highlighted.
Hi Viral.
Thanks for such a nicely documented blog. I tried implementing the above feature. I am able to get the json response at client side. But I am not getting the auto-populated drop down list. Any idea?
Hey great tutorial! I did everything but I got an error when I tried to run it. Can someone assist please? I get the error below:
HTTP Status 404 – /SpringMVC_Autocomplete/
type Status report
message /SpringMVC_Autocomplete/
description The requested resource (/SpringMVC_Autocomplete/) is not available.
Apache Tomcat/6.0.35
Update: sorry i forgot to put the index file in the right place…now i get a java error. one problem i noticed is that the project explorer view does not look like your example. I figure the reason is that i am using the lastest eclipse “cocoa” . Please advise, Here the java error…
HTTP Status 500 –
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:502)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:424)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:84)
org.springframework.web.servlet.support.RequestContextUtils.getWebApplicationContext(RequestContextUtils.java:81)
org.springframework.web.servlet.support.RequestContext.initContext(RequestContext.java:219)
org.springframework.web.servlet.support.JspAwareRequestContext.initContext(JspAwareRequestContext.java:74)
org.springframework.web.servlet.support.JspAwareRequestContext.(JspAwareRequestContext.java:48)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:76)
org.apache.jsp.index_jsp._jspx_meth_form_005fform_005f0(index_jsp.java:184)
org.apache.jsp.index_jsp._jspService(index_jsp.java:95)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.35 logs.
@BigCoder, It seems Spring is unable to locate your WebApplicationContext XML file. That is what the exception hints you – java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
Please check for the following –
1. By default, the naming convention of WebApplicationContext XML file is -servlet.xml. for e.g., if “springmvc” were the servlet name then the WebApplicationContext XML should be available in \WEB-INF folder with the name “springmvc-servlet.xml”
or
2. If you have named your WebApplicationContext XML file differently, not adhering to the above naming convention then you should specify the location and name of your WebApplicationContext XML in web.xml with a context parameter and a context loader listener to load it. See below for an example –
contextConfigLocation
/WEB-INF/
org.springframework.web.context.ContextLoaderListener
Hope the above steps will solve your problem.
I m getting the following error:
No matching handler method found for servlet request: path ‘/json/get_country_list.htm’, method ‘GET’, parameters map[‘term’ -> array[‘j’]]
My controller consists of:
Should i need to add something ??? I have added all the jars as in ur zip file..
please help…
@Anny, It seems the URL-Controller mappings in your WebApplicationContext XML file is incorrect. Please print the contents of your web.xml and WebApplicationContext XML to help you further.
Dear Patel,
I always found your tutorials very helpful and beneficial. This one however was quite a disappointment.
Should you be interested why please drop me an email.
Hi Peter, Thanks for the comment. The feedback that my blog visitors give is very important for me. Please feel free to share your inputs at viralpatel.net at gmail dot com.
Hi Viral,
first of all thanx for such a nice explanation.
In our project we are using tiles framework without annotation,in that case we have to always return ModelAndview Object.due to not using annotation we cannt set responsebody type as List in that case what type of data we should return for server side autocomplete feature??
Hi,
i am using autocompleter tag with struts2 , tiles framework and i want to change second autocompleter combo value based on first autocompleter combo list selection.
can you please, how it will done struts-dojo-tag. tell me the whatever the changes required in java script.
Hi Viral,
After downloading and configuring app in eclipse+tomcat only index.jsp is coming fine. None of the actions working fine.
Anything m missing?
Thanks.
By using autocomplete it works fine in IE browser but in Mozilla and Chrome there is a space between the textbox and the autocomplete list…… How to remove that space……
good viral!!!!!!!
Hi
I have done everything as you have explained still getting 404 error
“The requested resource (/SpringAutocomplete/index.html) is not available.”
can you please help
Nice tutorial … although when I run this in Tomcat I get a “406” error for every http://…/get_country_list.html?term=XXX call. So there’s no autocompletion in the form. I’d better double-check that I have copied the setup correctly …
Found it: I forgot to include the jackson-core-asl and jackson-mapper libraries. Now the tutorial works as expected.
I get a 404 error
HTTP Status 404 –
type Status report
message
descriptionThe requested resource () is not available.
GlassFish Server Open Source Edition 3.1.1
PLEASE HELP!
Hi Viral,
Can you tell me what is ‘term’ in the below mentioned line
For the country input field, where do you define the “term” parameter? I guess that I echo the same question asked by Sandy.
hello i follow the tutorial everything ok but the dropdown list doesnt show up? anybody that solved this issue?
not even i made single changes and works fantastic…thanks for such tutorails..go bless..
If you enter a letter into an amount field, accidentally or intentionally, when you leave the field the letter will be replaced by 0.00. If not removed this will be what you submit.
The amount field can be found throughout the site on the transaction screen, reports and search screens.
provide logic using the spring mvc ,hibernate.if end user enter the non neumeric value then need to set the default value like 0.00(amount field)
It is a great tutorial. I made it work on IE immediately. But it does not work on Firefox. Neither Country nor Technologies has pop-up windows to display the possible choices as it does on IE. I check that the Block pop-up window is NOT checked. For those who made it work, does it work on Firefox?
it is great tutorial.
It really helped me to configure json in spring 3.0. Big thank Viral :)
error with save data in order to view JSON Object.
please help me, to be run …
Thanks.
I am getting the below error after doing all the steps as mentioned.
java.lang.IllegalStateException: Mode mappings conflict between method and type level: [/get_search_list] versus [VIEW]
Note: I have used my existing controller and there I have used type level mode as view for @RequestMapping.
Please suggest what change I need to do to make it run.
Thanks.
How to implement same with DB tables.
thanks for share !
dear Viral,
i need some help from you
we are small team and new for Java base web application development.
now we have one web vase financial application project have to develop in Java.
i need help for selecting MVC technology
like JSF+hibernet+spring+EJB and Jsper report for report, Jboss as AS etc
please guide me which combination is best
with regards and thanks
Anand
nice stuff:)
Thanks dude…works very well…just what I was looking for!
I am getting following error could you help me
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name ‘country’ available as request attribute
i am new to spring
Hi, I am getting the below exception. I have checked everything fine. Kindly help.
Jun 13, 2013 2:34:24 PM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/Spring3MVC_Multiple_Row_Submit/save.html] in DispatcherServlet with name ‘spring’
Thanks,
Karthik.
Hi,
Iam getting following error.please kindly help me out of this
WARNING: No mapping found for HTTP request with URI [/Spring3MVC_Multiple_Row_Submit/index.html] in DispatcherServlet with name ‘spring’
Hi Viral,
I base on your source code and developed autocomplete spring and json get list country from database mysql.
Dao Class:
My Controller
And user.jsp
I have run successful but when I input ‘India’ textbox, it is not display list country from databse
If you resolved for me, please inbox for me, my email: [email protected]
Thanks Viral patel very much.
Hey Viral Patel….
gr8 tutorials…
but i have a problem….
i need to get the data in the autocomplete from the database and not from the dummy database…
so could you help me with such an example….
i use mysql…..
thank you in advance…….
hi viral, i have one problem in one spring web mvc example:
i have on bean in dispatcher-servlet.xml file, i inject this bean in one java class (normal java class) then it inject property, but my problem is when i inject this bean into controller class (spring annotation base controller) then i got some exception. the dispatcher-servlet.xml is->
And the controller is like ->
i need multiple values in single text box separated by commas with out using spring
Hi viral, when i running these application , m getting following exception:- plz rectify the save logic in controller class
WARNING: No mapping found for HTTP request with URI [/SpringMVCWithJqueryAndJsons/save.html] in DispatcherServlet with name ‘spring’
Good one…
download and set up to run
1) eclipse project and java resource side has error symbols but internal has no error
2) does now work as it said
Hi Viral.
Thanks for such a nicely documented blog. I tried implementing the above feature. I am able to get the json response at client side. But I am not getting the auto-populated drop down list. help me.
Hi,
thanks. I have been able to run this successfully. Just want to know if we can modify this code to include images too in our results. Just like facebook search like when we search a page or a person. So then when we click on the list item , it opens the person’s page or any other page. .
Thanks
NIce article with example…keep it up :)
Hi Viral,
Can you give me example code with ajax posting to spring mvc controller with request param.
Awesome,
Thanks Viral
I tried so many example but at the end your examples are working fine.
Thanks Viral !!!!
hi can you explain to me how did the ‘term’ get its value in the controller?
wow very nice post.
can u tell me where come from the “query” in the getCountryList()?
would u tell me where come from the ‘query’ ?
hey where there’s no ajax and jquery in your coding
Hi, anyone can explain how terms is got? because on this part of code, they don’t define “terms” even though is a @requestParam, anyway “terms” is defined on technologies javascript code but I dont know why it’s possible to get it by request.param
$( “#country” ).autocomplete({
source: ‘${pageContext. request. contextPath}/get_country_list.html’
});
dear patel
i want to make categories of product for Example
Mobile
Nokia 1100
Nokia 2600
Man’s
exa1
exa2
the above type i want to make using spring mvc and mongodb
i am inserting the Document parent and child type so please suggest me how can i do in jsp page
The value is passing in to the controller but the suggestion is not comming in the jsp page plz help me.When i save the data the exception shown (“HTTP Status 500 – Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: The current request is not a multipart request”).