Spring is one of the most widely used Java EE frameworks. We have earlier seen how to use Spring MVC to create Java-based web applications. Today we will learn to create Spring Restful Web Services using Spring MVC and then test it out with the Rest client. In the end, we will also look into how to invoke Spring Restful web service using Spring RestTemplate API.
We will use Spring latest version 4.0.0.RELEASE and utilize Spring Jackson JSON integration to send JSON response in the rest call response. The tutorial is developed in Spring STS IDE for creating Spring MVC skeleton code easily and then extended to implement Restful architecture. Create a new Spring MVC Project in the STS, our final project will look like the below image. We will look into each of the components one by one.
Our pom.xml file looks like below.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev</groupId>
<artifactId>SpringRestExample</artifactId>
<name>SpringRestExample</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.6</java-version>
<org.springframework-version>4.0.0.RELEASE</org.springframework-version>
<org.aspectj-version>1.7.4</org.aspectj-version>
<org.slf4j-version>1.7.5</org.slf4j-version>
<jackson.databind-version>2.2.3</jackson.databind-version>
</properties>
<dependencies>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind-version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
STS tool generates the pom.xml file for us. However, I have updated the Spring Framework, AspectJ, SLF4J and Jackson version to the latest one as of today. Most of the part is common and generated automatically, the important point to note is that I have added Jackson JSON libraries in the dependency because we will use that to convert Objects to JSON and vice versa.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
This file is generated automatically and I haven’t changed anything in that. However, if you want to change context configuration files and their location, you can do it in the web.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
</beans>
This file contains the shared resources that will be visible to all the web components, we will be developing a simple rest service and that’s why I haven’t changed anything here.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!-- Configure to plugin JSON as request and response in method handler -->
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter"/>
</beans:list>
</beans:property>
</beans:bean>
<!-- Configure bean to convert JSON to POJO and vice versa -->
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</beans:bean>
<context:component-scan base-package="com.journaldev.spring.controller" />
</beans:beans>
Most of the part is auto generated and contains boiler-plate configurations. However important points to note are annotation-driven element to support annotations based configuration and plugging in MappingJackson2HttpMessageConverter
to the RequestMappingHandlerAdapter
messageConverters
so that Jackson API kicks in and converts JSON to Java Beans and vice versa. By having this configuration, we will be using JSON in request body and we will receive JSON data in the response.
Let’s write a simple POJO class that will serve as input and output to our Restful web service methods.
package com.journaldev.spring.model;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
public class Employee implements Serializable{
private static final long serialVersionUID = -7788619177798333712L;
private int id;
private String name;
private Date createdDate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonSerialize(using=DateSerializer.class)
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
}
The only important point to note is the use of @JsonSerialize
annotation to use DateSerializer
class for Date conversion from Java type to JSON format and vice versa.
We will have the following rest web services endpoints.
Sl. No | URI | HTTP Method | Details |
---|---|---|---|
1 | /rest/emp/dummy | GET | Health Check service, to insert a dummy data in the Employees data storage |
2 | /rest/emp/{id} | GET | To get the Employee object based on the id |
3 | /rest/emps | GET | To get the list of all the Employees in the data store |
4 | /rest/emp/create | POST | To create the Employee object and store it |
5 | /rest/emp/delete/{id} | PUT | To delete the Employee object from the data storage based on the id |
We have a class defining all these URI as String constants.
package com.journaldev.spring.controller;
public class EmpRestURIConstants {
public static final String DUMMY_EMP = "/rest/emp/dummy";
public static final String GET_EMP = "/rest/emp/{id}";
public static final String GET_ALL_EMP = "/rest/emps";
public static final String CREATE_EMP = "/rest/emp/create";
public static final String DELETE_EMP = "/rest/emp/delete/{id}";
}
Our EmployeeController class will publish all the web service endpoints mentioned above. Let’s look at the code of the class and then we will learn about each of the methods in detail.
package com.journaldev.spring.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.journaldev.spring.model.Employee;
/**
* Handles requests for the Employee service.
*/
@Controller
public class EmployeeController {
private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class);
//Map to store employees, ideally we should use database
Map<Integer, Employee> empData = new HashMap<Integer, Employee>();
@RequestMapping(value = EmpRestURIConstants.DUMMY_EMP, method = RequestMethod.GET)
public @ResponseBody Employee getDummyEmployee() {
logger.info("Start getDummyEmployee");
Employee emp = new Employee();
emp.setId(9999);
emp.setName("Dummy");
emp.setCreatedDate(new Date());
empData.put(9999, emp);
return emp;
}
@RequestMapping(value = EmpRestURIConstants.GET_EMP, method = RequestMethod.GET)
public @ResponseBody Employee getEmployee(@PathVariable("id") int empId) {
logger.info("Start getEmployee. ID="+empId);
return empData.get(empId);
}
@RequestMapping(value = EmpRestURIConstants.GET_ALL_EMP, method = RequestMethod.GET)
public @ResponseBody List<Employee> getAllEmployees() {
logger.info("Start getAllEmployees.");
List<Employee> emps = new ArrayList<Employee>();
Set<Integer> empIdKeys = empData.keySet();
for(Integer i : empIdKeys){
emps.add(empData.get(i));
}
return emps;
}
@RequestMapping(value = EmpRestURIConstants.CREATE_EMP, method = RequestMethod.POST)
public @ResponseBody Employee createEmployee(@RequestBody Employee emp) {
logger.info("Start createEmployee.");
emp.setCreatedDate(new Date());
empData.put(emp.getId(), emp);
return emp;
}
@RequestMapping(value = EmpRestURIConstants.DELETE_EMP, method = RequestMethod.PUT)
public @ResponseBody Employee deleteEmployee(@PathVariable("id") int empId) {
logger.info("Start deleteEmployee.");
Employee emp = empData.get(empId);
empData.remove(empId);
return emp;
}
}
For simplicity, I am storing all the employee’s data in the HashMap empData. @RequestMapping annotation is used to map the request URI to the handler method. We can also specify the HTTP method that should be used by client application to invoke the rest method. @ResponseBody annotation is used to map the response object in the response body. Once the response object is returned by the handler method, MappingJackson2HttpMessageConverter kicks in and convert it to JSON response. @PathVariable annotation is the easy way to extract the data from the rest URI and map it to the method argument. @RequestBody annotation is used to map the request body JSON data into the Employee object, again this is done by the MappingJackson2HttpMessageConverter mapping. Rest of the code is simple and self-understood, our application is ready for deployment and testing. Just export as WAR file and copy it in the servlet container web app directory. If you have the server configured in the STS, you can simply run it on the server to get it deployed. I am using WizTools RestClient to invoke the rest calls but you can also use Chrome extension Postman. Below screenshots shows the different invocations of the rest APIs exposed by our application and it’s output. Health Check - Get Dummy Employee Rest Call Create Employee POST Rest Call: Make sure request Content-Type is set to “application/json” otherwise you will get HTTP Error Code 415.
Get Employee Rest Call
Delete Employee Rest Call
Get All Employees Rest Call
Rest Clients are good to test our rest web service but most of the times, we need to invoke rest services through our program. We can use Spring RestTemplate
to invoke these methods easily. Below is a simple program invoking our application rest methods using RestTemplate API.
package com.journaldev.spring;
import java.util.LinkedHashMap;
import java.util.List;
import org.springframework.web.client.RestTemplate;
import com.journaldev.spring.controller.EmpRestURIConstants;
import com.journaldev.spring.model.Employee;
public class TestSpringRestExample {
public static final String SERVER_URI = "https://localhost:9090/SpringRestExample";
public static void main(String args[]){
testGetDummyEmployee();
System.out.println("*****");
testCreateEmployee();
System.out.println("*****");
testGetEmployee();
System.out.println("*****");
testGetAllEmployee();
}
private static void testGetAllEmployee() {
RestTemplate restTemplate = new RestTemplate();
//we can't get List<Employee> because JSON convertor doesn't know the type of
//object in the list and hence convert it to default JSON object type LinkedHashMap
List<LinkedHashMap> emps = restTemplate.getForObject(SERVER_URI+EmpRestURIConstants.GET_ALL_EMP, List.class);
System.out.println(emps.size());
for(LinkedHashMap map : emps){
System.out.println("ID="+map.get("id")+",Name="+map.get("name")+",CreatedDate="+map.get("createdDate"));;
}
}
private static void testCreateEmployee() {
RestTemplate restTemplate = new RestTemplate();
Employee emp = new Employee();
emp.setId(1);emp.setName("Pankaj Kumar");
Employee response = restTemplate.postForObject(SERVER_URI+EmpRestURIConstants.CREATE_EMP, emp, Employee.class);
printEmpData(response);
}
private static void testGetEmployee() {
RestTemplate restTemplate = new RestTemplate();
Employee emp = restTemplate.getForObject(SERVER_URI+"/rest/emp/1", Employee.class);
printEmpData(emp);
}
private static void testGetDummyEmployee() {
RestTemplate restTemplate = new RestTemplate();
Employee emp = restTemplate.getForObject(SERVER_URI+EmpRestURIConstants.DUMMY_EMP, Employee.class);
printEmpData(emp);
}
public static void printEmpData(Employee emp){
System.out.println("ID="+emp.getId()+",Name="+emp.getName()+",CreatedDate="+emp.getCreatedDate());
}
}
Most of the program is simple to understand, however when invoking rest method returning a Collection, we need to use LinkedHashMap
because JSON to object conversion doesn’t know about the Employee object and converts it to the collection of LinkedHashMap
. We can write a utility method to convert from LinkedHashMap
to our Java Bean object. When we run the above program, we get the following output in the console.
ID=9999,Name=Dummy,CreatedDate=Tue Mar 04 21:02:41 PST 2014
*****
ID=1,Name=Pankaj Kumar,CreatedDate=Tue Mar 04 21:02:41 PST 2014
*****
ID=1,Name=Pankaj Kumar,CreatedDate=Tue Mar 04 21:02:41 PST 2014
*****
2
ID=1,Name=Pankaj Kumar,CreatedDate=1393995761654
ID=9999,Name=Dummy,CreatedDate=1393995761381
Another point is that RestTemplate
put methods doesn’t have option to set response object because PUT method should be used to store something on the server and a simple HTTP 200 status code should be sufficient.
Download Spring Restful Webservice Project
That’s all for the Spring Restful web application tutorial. Download the sample project from the above link and play around with it to learn more. UPDATE: Because of so many requests to provide similar example with XML as well as supporting both XML and JSON, I have extended this application in Spring REST XML JSON Example to support both XML and JSON requests and response. I strongly suggest you go through that to see the beauty of the spring framework and how easy it is to achieve this.
You can download complete project from our GitHub Repository.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Great work, very helpful.
- sreeni
please share the complete project code.
- mallikarjuna Rao
it was an issue with the plugin I use for managing downloads, solved it. Please try now.
- Pankaj
I cannot tell you how thankful I am for this. After banging my head against the wall for half the day you have given me the “magic” configuration that will correctly return json from my REST controllers. Thank you, thank you, thank you! Note to anyone using Spring 4 and getting a 406 HTTP response when trying to make a call to your controllers: just copy the spring-context.xml file on this page and be done with it.
- Scott
Thanks for the kind words, I really appreciate it.
- Pankaj
this example is not in readable when I extract it. please provide complete example with source. Thanks Mallik
- mallikarjuna rao
its asking user name and password while extracting. zip file does not contain any files with out username and password.
- mallikarjuna rao
Thanks a lot boss, quick reference. Small doubt, in controller class, while creating employee you are purring created emp in to a map ( empData ) , but you are returning pojo class object ( emp ). Why so ? Any ways Thanks !
- ashok
Here Map is our data storage system that holds all the Employee objects. Based on the rest call, we are returning one employee or list of employees.
- Pankaj
Thank you Pankaj. I am new to spring, just trying to understand your example and implement it in my app. One more doubt, i am using spring 3.0.5, would like to use same service in webapp and mobile client. depends up on request, i’ve to send response. if request from webapp, have to send ModelViewObject which will go through ViewResolver. if it is from Mobile, have to send JOSN object Could it possible ? if so please help on configurations. Thanks in advance. Ashok
- ashok
I am trying to do an API that will receive a list of Customers for example an this list is processed by the service, but I have some questions: - If I receive the list of Customers inside the Body as @RequestBody then how should I process it. - My controller must process all in a once because we have to process all the customers or none. - I am trying to deserialize the Jason content to a lIst of customers, but after this I should process customer by customer invoking the service n times but my transactions are at service level not at controller level. . Could you please give me any idea about how to do it? I am doing my final degree work and I am really stuff by this. Many thanks, Ana
- Ana
Once you have received the list in controller request handler method, its upto you how to process it. I am assuming there will be some DB calls, third party calls etc. You can iterate over the list and do it one by one or in batch.
- Pankaj
Can we make this application to support any kind of format(json,xml, etc) to generate and also to receive …?
- Narayana
How did you come up with the name “spring Jackson” for your program?..spring Jackson, oregon
- spring788@hotmail.com
Thats a coincidence, Spring and Jackson both are Java frameworks. :)
- Pankaj
I want to expose rest service to receive byte array, so in my service i used @RequestBody final byte[] byteArray This is resulting me below exception org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of byte[] out of START_OBJECT token Could you please help me out in this.
- Anil
you can’t sent byte[] because as error says, it should be a serialized object.
- Pankaj
Sir at which you have used restful web services i mean how to know that this application using restful web service. ?? please make me clear… Thanks
- Bhabadyuti
I think you should read about Restful on wikipedia.
- Pankaj
Perfect!, first example i see to extract the paths with enums, now take it to the next level and implement Hateoas? :)
- Mortier
You should really overthink your “RESTful” URL design in this example. RESTful URLs do not have any verbs in them, just nouns. So the right URLs for your example would be: GET /employees (get a list of all employees) POST /employees (create a new employee) GET /employees/id (get a specific employee from id) DELETE /employees/id (delete a specific employee from id) Although I appreciate your motiviation to provide examples for other people on the internet, you should ensure that you do not teach wrong things.
- Thomas
Yes you are right, but it’s for example only to show how it works. I am sure if you are working on a real project, you will have your own Rest URIs and won’t go for this structure. The takeaway of this tutorial is to learn how to implement Restful web service in Spring.
- Pankaj
How can I implement spring validators in the example? I saw that you have already explained spring validators in Post.
- Mohan
I am new to spring, i have imported your project but getting error in servlet-contex.xml error like, Class ‘org.springframework.http.converter.json.MappingJacksonHttpMessageConverter’ not found [config set: SpringRestExample/web-context]
- ranjith
Check your spring version and jars for this class.
- Pankaj
Hi, I have deployed the above code in WAS 7. getting below error. Permission: getenv.* : Access denied (java.lang.RuntimePermission getenv.*) Code: org.springframework.core.env.AbstractEnvironment in {file:/opt/httpd/root/apps/sample/ibm7/dev-ear/sample.war/WEB-INF/lib/spring-core-4.0.0.RELEASE.jar} Could you please suggest me how can i override this error. I have tried the below optins, but no luck 1) added below two lines in root-context.xml 2) added below line in spring.properties copied in classes folder spring.getenv.ignore=true Thanks, Pradeep.
- Pradeep
added below code in root-context.xml but no luck
- Pradeep
From the error it looks like permission issue, I have never faced this issue but one pointer I can give you is to check any security manager configuration or policy files are present that is preventing environment variables access?
- Pankaj
Thanks, the example works (which is not so common with many EE examples) and is reduced to a minimum to demonstrate just the technology without any useless patterns show-off, I really like it…
- Michal Skultety
Its a good example to begin with. Easy to understand than other tutorials related to Spring RESTful Services. I used STS and created this project as Spring MVC. I didn’t download your project. But created the structure and contents as mentioned here. I deployed with VMware vFabric tc Server Developer Edition v2.9 … Its looks to be deployed properly but on invocation getting 404. Tried with as well as in Tomcat 7 also same issue. Getting 404 in browser as well as in WizTools RestClient 3.2.2 I created a Sample Dynamic Web project, that got deployed and its rendering the required output. There is only one warning in the server console and i searched in Web, its mentioned nothing to worry about this. WARNING: [SetContextPropertiesRule]{Context} Setting property ‘source’ to ‘org.eclipse.jst.jee.server:SpringRestExample’ did not find a matching property. Your advice would be helpful. I can attach the server log if needed.
- Nagaraj
I downloaded the Project and tried. Even then getting the same issue.
- Nagaraj
Today changed jre settings and deployed. I could see some errors in the console. Please let me know if you are getting any idea based on the error trace below. SEVERE: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring]] Caused by: java.lang.NoClassDefFoundError: org/springframework/web/context/WebApplicationContext SEVERE: Error deploying configuration descriptor C:\MarketPlace\DevTools\SpecialProject\springsource\vfabric-tc-server-developer-2.9.3.RELEASE\base-instance\conf\Catalina\localhost\spring.xml java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring]]
- Nagaraj
Nagaraj , did u get any soln reg this i tried many soln which mentionedin hte net. like 1. remove all servers and clear the servers folder in eclipse workspace folder 2. clean, publish, etc, 3. adding common-loggins jar to dependency. None woks out, could u please help me with your soln…
- Anand
HI Pankaj, Its really great article. there are no files in the zip file when I open that. could you please share the complete project. Best Regards Mallik
- mallikarjuna rao
nothing is there in u r downloaded file yaar…
- Nagaraju
it was an issue with the plugin I use for managing downloads, solved it. Please try now.
- Pankaj
Hi , I want to write a jersey client for file upload (which is a spring rest) @RequestMapping(method = RequestMethod.POST,consumes = “multipart/form-data”) @ResponseBody public String upload(@RequestParam(“file”) MultipartFile file) this is how my code will look like. Please provide me some idea.I tried with some example but i am getting this error org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=multipart/form-data, type=class com.sun.jersey.multipart.MultiPart, genericType=class com.sun.jersey.multipart.MultiPart.
- Sudha
Your download link still has a problem. After downloading, the file size is only 9K and nothing in the zip file except “.settings” directory. Could you please verify? Thank you.
- Sam
Sorry about that, I have fixed it and verified myself, it should be working fine now.
- Pankaj
First of all thanks for the tutorial, it has helped me a lot, try to test the createEmployee method, however I did not succeed, try it through a jsp with ajax and then try using postman, I think the problem is trying to send objects and hope you can help me, greetings from Mexico.
- Víctor Hernández
Good explanation but I don’t find any URL to download your project after following you on twitter
- smartboy
Hi Pankaj, Thank you very much for this nice and thorough article. I followed it through and was able to successfully test it without using WizTools RestClient. I just have one question: I found your article by search “Spring Rest service eclipse json” on google. I was expecting the response format is in Json. When you get a chance, could you explain how to get the response in Json? Thanks, Wendy
- Wendy
Extremely helpful tutorial :) I have a small doubt : In pom.xml I ad to comment this : and instead have to add this : org.springframework spring-tx 4.0.0.RELEASE And then why pom.xml reports “ArtifactTransferException: Failure to transfer org.springframework:spring-context:jar:4.0.0.RELEASE from https://repo1.maven.org/maven2 was cached in the local repository,…” ? I have cleared the local repository after that, but the problem still persists. Any suggestions please :)
- Rahul
You need to force update the dependencies. you need to have constant defined for yhe versions.
- Pankaj
This line can be changed
restTemplate.getForObject(SERVER_URI+EmpRestURIConstants.GET_ALL_EMP, List.class
torestTemplate.getForObject(SERVER_URI+EmpRestURIConstants.GET_ALL_EMP, Employee[].class
Now you have aray of mapped Employees and can easily create any collection.- Volodia
Thank you for this article. This is really helpful. Thanks a ton.
- Rohit
How could we have XML as Response. I have a requirement to have my GET call response back with Json or XML as per client request. Please advise.
- Shiv
Hello! Really good job! it’s the first project which work without editing somethings. I have a question how to create an user without the Java program, I tryed this request but without success… Have you got an issue? curl -X POST -H “Content-type:application/json” -H “Accept:application/json” -d ‘{“id”:2,“name”:“JBlabel”}’
https://localhost:8080/SpringRestExample/rest/emp/create
- Jorel
I got the same problem here on a Win 7 System. I read that there could be some problems with curl for windows (if you use that). In that case the syntax :
curl https://localhost:8080/SpringRestExample/rest/emp/create -X POST -H "Content-type:application/json" -d @json.txt
worked for me with the json inside the txt file. Seems to be an issue with the single quotes in win command line. Cygwin should also do the job. Best regards, Lars- Lars
Hi!, firstly thank you for this great work. And secondly, could you post something about how to serialize a Hibernate model class (make a JSON), please. I tried to convert the Employee class model to a Hibernate class model, and then get data directly from a database. But a get this error : “Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.journaldev.spring.model.Person_$$_jvstf07_0[“handler”]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.journaldev.spring.model.Person_$$_jvstf07_0[“handler”])” All works great if I make a data bind between a new POJO Employee model and his Hibernate model counterpart. Thanks!
- lsm
implement Serializable interface
- devloper
Great article! I am able to create web service using this article, thank you so much!
- devloper
thanks your code helps me a lot
- gurjinder singh
I tried downloading the example, and importing to eclipse. When I tried running the application on server. ( after doing the mvn-clean and install - both complete successfully) I get a 404 with a warning message on the console : WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/SpringRestExample/] in DispatcherServlet with name ‘appServlet’ Any idea what I’m doing wrong here?
- Vinod
Hello Pankaj, I appreciate your efforts for us like beginner. I went through your blog and followed instruction its working perfectly alright. I have small doubt. If I have controller with 1 function @RequestMapping(value=“/getvalue”, method=RequestMethod.GET) public String getStatastics(String string1, String string2, String string3, EnumDemo demo, Model model){ String resultedString = string1 + string2 + string3; System.out.println(demo.enumValue1); return resultedString; } Now I want to create client with calling this above function. I would be really happy if you provide me some direction. Thanks.
- Rohit More
Thanks. I have one question. suppose if i use browser as my client to access - testGetAllEmployee(). i.e in broweser if i call url for testGetAllEmployee() then i want show all details in html/css format instead of json format. how can i do it?
- chan
could you pls send me the sample project. I do not have a google account. tks for much. mail address: 8923040@qq.com
- simon
When I run the example the URL I must use is
https://localhost:8080/spring/
and nothttps://localhost:8080/SpringRestExample/
. What is it that is determining “spring” vs. “SpringRestExample” in the URL? I though this was based on the application name. I ran your Spring MVC example and the URL islocalhost:8080/SpringMVCExample/
as expected. I have compared the two projects and I cannot see a difference that would map the url differently.- CH
first of all good work and thanks for the effort. I have a rather silly question, if my client is a web browser like mozilla, to create an employee: What would be the proper url string for this service using JSON notation? ie “https: // localhost:8080/SpringRestExample/rest/emp/create ???” Thanks in advance
- Mario M.
WARN : org.springframework.web.client.RestTemplate - GET request for “https://localhost:8080/SpringRestExample/rest/emp/dummy” resulted in 404 (Not Found); invoking error handler I am trying to debug but I am getting the warinning above. I placed a break in TestSpringRestExample and it is breaking in RestTemplate in response.close(); protected T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor responseExtractor) throws RestClientException { … finally { if (response != null) { response.close(); }
- Demetrio
Hi Pankaj, Thanks for your clear example, I really enjoy to read tutorials you’ve provided, it is awesome. I’m trying to provide an API for my project and I’ve used Jackson convertor, it works fine however I need to add xml convertor to my API as well (e.g. /api/rest/xml besides /api/rest/json and so on). I realized a message convertor like MappingJackson2HttpMessageConverter should be added but I’m not sure how can I distinguish XML requested not JSON? it seems this convertors will convert all requests to JSON and Objects vice versa. Could you please let me know how to solve it, thanks a lot.
- Mohammad
Great help in this tutorial. It’s really useful for people who aren’t using Spring Boot- thanks!
- Dakota