In this tutorial, we will be learning how a RESTful service can be built with Spring. We would be creating a simple Restful service using spring and running it in eclipse.
Tools
We will be using the following tools for development in this tutorial.
- Maven 3.3.9
- Java 1.8.0.101
- Spring Tool Suite [ standalone or eclipse plugin]
- SoapUI for testing.
We will be providing step by step guide on how to create a REST service using Spring. We are going to create a Rest Service where GET, PUT, POST and DELETE requests are handled.
Spring Tool Suite
Spring Tool Suite(STS) is a tool for spring development. It is developed on top of Eclipse. STS can be downloaded as a separate software from the official site or can be added to existing Eclipse IDE via Eclipse Marketplace. While downloading from official STS download site, make sure that you download the correct version according to the OS [32 bit or 64 bit].
With the introduction of Spring Tool Suite(STS), we no longer need to manually write the whole set of configurations that are required for Spring Application development.
Building The Project Structure With STS
- Open STS. The default perspective of the STS IDE will be Spring perspective.
- Right click on package explorer. From the drop down, choose New -> Spring Legacy Project. Select Spring MVC Project as shown in the diagram below

After creation, your final project may look like the following in the package explorer.

Adding Required Dependencies in pom.xml
STS will add default dependencies to the project’s pom.xml. We have done slight modifications to the generated pom.xml so that our application uses the latest and updated dependencies. The changed versions are given in the properties tag.

Note the name of the artifactID at the start of project configuration in your pom.xml. After successful creation of a new service in the Spring MVC Application, the application can be deployed onto a web container and is usually accessed by following URL format:
http://localhost:8080/<artifactID>/<your-controller-or-method-path-value>
After required changes are made to pom.xml, run the following in command prompt
1 2 |
mvn eclipse:clean mvn eclipse:eclipse |
On the first run, this should download all the dependencies to the M2_HOME(system property) folder. All the required libraries would be downloaded and added to the classpath of the eclipse project.
Gradle dependencies
If your organization or CI tool uses Gradle for building projects, you can generate the Gradle build file from pom.xml. For this purpose, navigate to the root directory of your project structure and run:
gradle init
This should create a build.gradle file that contains the dependencies per the maven and java settings in your system. The Gradle file created for sample project is given below for reference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
apply plugin: 'java' apply plugin: 'maven' group = 'com.javatutorials' version = '1.0.0-BUILD-SNAPSHOT' description = """RestWithSpringLegacy""" sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { maven { url "http://repo.maven.apache.org/maven2" } } dependencies { compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version:'2.8.8.1' compile(group: 'org.springframework', name: 'spring-context', version:'4.3.8.RELEASE') { exclude(module: 'commons-logging') } compile group: 'org.springframework', name: 'spring-webmvc', version:'4.3.8.RELEASE' compile group: 'org.aspectj', name: 'aspectjrt', version:'1.8.10' compile group: 'org.slf4j', name: 'slf4j-api', version:'1.7.25' compile group: 'javax.inject', name: 'javax.inject', version:'1' compile group: 'javax.servlet', name: 'jstl', version:'1.2' runtime group: 'org.slf4j', name: 'jcl-over-slf4j', version:'1.7.25' runtime group: 'org.slf4j', name: 'slf4j-log4j12', version:'1.7.25' runtime(group: 'log4j', name: 'log4j', version:'1.2.15') { exclude(module: 'mail') exclude(module: 'jms') exclude(module: 'jmxtools') exclude(module: 'jmxri') } testCompile group: 'junit', name: 'junit', version:'4.12' providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5' providedCompile group: 'javax.servlet.jsp', name: 'jsp-api', version:'2.1' }</code> |
After successful creation of the first REST application, you may invoke Gradle build by the following command:
gradle build
Understanding the Configuration XMLs
web.xml
This is the deployment descriptor and entry point to all configurations for a Spring MVC project. In any J2EE application, the web.xml primarily contains two important tags: a. <servlet> tag that contains the servlet’s name and other parameters. B. <servlet-mapping> tag that maps the servlet to a URL pattern. In the case of Spring MVC application, we use only one servlet in most cases, that is, org.springframework.web.servlet.DispatcherServlet.
This servlet will delegate the incoming request to corresponding Java controller implementation according to the headers of the request.
Servlet-context.xml and root-context.xml
There are two types of application contexts in Spring: root-context and servlet-context for each servlet. The dispatcherServlet shares the root-context. The root-context is also called the spring parent context. Spring container on startup reads beans from the root-context. The servlet-context also contains bean configurations. While trying to locate a bean, Spring framework searches the servlet context at first, and if not found, it will search for the bean in root-context.
Note: In this tutorial, we are not going to modify these three XML files as that is out of scope. We will be focussing more on REST related concepts here.
Create POJO for your service
Create the following class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.javagists.rest.model; import java.io.Serializable; public class Account implements Serializable { private static final long serialVersionUID = -7681240698211451523L; private int id; private String fullName; private Double balance; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public Double getBalance() { return balance; } public void setBalance(Double balance) { this.balance = balance; } } |
Create a REST Controller
In Spring MVC, HTTP requests are handled by controllers that are annotated with @Controller annotation. If we do not specify the MIME type using @Produces, the POJO will be converted to default JSON format and returned to respective REST calls.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
package com.javagists.rest; import java.util.*; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.javatutorials.rest.model.Account; import static com.javatutorials.rest.util.Constants.*; @Controller public class AccountsController { Map<Integer, Account> accountMap = new HashMap<Integer, Account>(); @RequestMapping(value = GET_DEFAULT, method= RequestMethod.GET) public @ResponseBody Account getDefault(){ Account acc; if(accountMap.get(0) != null){ acc = accountMap.get(0); } else { acc = new Account(); acc.setId(0); acc.setFullName("John Smith"); acc.setBalance(0.00); accountMap.put(0, acc); } return acc; } @RequestMapping(value = GET_ONE, method = RequestMethod.GET) public @ResponseBody Account getOneAccount(@PathVariable("id") int id){ return accountMap.get(id); } @RequestMapping(value = GET_ALL, method = RequestMethod.GET) public @ResponseBody List getAllAccounts(){ Collection accs = accountMap.values(); List returnList = new ArrayList(); returnList.addAll(accs); return returnList; } @RequestMapping(value = GET_ALL, method = RequestMethod.POST) public @ResponseBody Account addNewAccount(@RequestBody Account acc){ accountMap.put(acc.getId(), acc); return acc; } @RequestMapping(value = GET_ONE, method = RequestMethod.PUT ) public @ResponseBody Account modifyAccount(@PathVariable("id") int id, @RequestBody Account acc){ Account oldAcc = accountMap.get(acc.getId()); if(oldAcc == null){ accountMap.put(acc.getId(), acc); } else { accountMap.remove(acc.getId()); accountMap.put(acc.getId(), acc); } return acc; } @RequestMapping(value = GET_ONE, method = RequestMethod.DELETE) public @ResponseBody Account deleteAccount(@PathVariable("id") int id){ Account oldAcc = accountMap.get(id); accountMap.remove(id); return oldAcc; } } |
The Constants used in above program are defined below:
1 2 3 4 5 6 7 8 9 10 11 12 |
package com.javagists.rest.util; public interface Constants { String DELIMITTER = "/"; String ACCOUNTS = "accounts"; String DEFAULT = "default"; String ID = "{id}"; String GET_ALL = DELIMITTER + ACCOUNTS; String GET_DEFAULT = GET_ALL + DELIMITTER + DEFAULT; String GET_ONE = GET_ALL + DELIMITTER + ID; } |
Overview Of The Annotations Used
Annotations | Description |
@Controller | Denotes that the particular class serves as a controller that an cater to an incoming request |
@RequestMapping | Used to map an entire controller or a method of the controller. This contains parameters like URI, Media types produced, media types consumed and the HTTP method which shall invoke it. |
@ResponseBody | Used to denote that the return value of the method will be what the response for HTTP request will comprise of. |
@PathVariable | Denotes the path parameter. Eg: http://localhost:8080/rest/accounts/1. Here, 1, which corresponds to account ID will be taken as path variable. |
Running And Testing The Application
In STS IDE, right-click on the server and choose Add or Remove. Add your project and then start it.
On a web browser, type the following URL:
http://localhost:8080/rest/accounts/default
You should be able to see the following JSON as output:
{"id":0,"fullName":"John Smith","balance":0.0}
Testing CRUD operations
Download SOAPUI from the official download site and install it in your system. Give the URL: http://localhost:8080/rest/accounts
and start the REST test.
You should be able to perform GET, POST, PUT and DELETE requests prop.A sample screenshot is given below for create (POST) operation:
