How to write RESTful web services using spring 3 mvc

You have learned that how to write the RESTful web services and also how to write Spring 3 web application. Now, its time to combine them so that your spring web application shall work like RESTful webservices also.

Download source code

For writing this application, I am modifying the source code written in previous post. So, if want, you can download from there or you have it from above download link.

Step 1) Update pom.xml to add support of JAXB and Jackson (for xml and json formats).

	<dependency>
      <groupid>org.codehaus.jackson</groupid>
      <artifactid>jackson-mapper-asl</artifactid>
      <version>${jackson-mapper-asl.version}</version>
      <scope>runtime</scope>
	</dependency>

	<dependency>
      <groupid>javax.xml.bind</groupid>
      <artifactid>jaxb-api</artifactid>
      <version>${jaxb-api.version}</version>
      <scope>runtime</scope>
	</dependency>

Do not forget to run “mvn eclipse:eclipse -Dwtpversion=2.0” command on command prompt again, to update the project dependencies.

Step 2) Update bean configuration file (spring-mvc-servlet.xml) for view resolvers.

<mvc:annotation-driven />

<context:component-scan  base-package="com.howtodoinjava.web" />

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
	<property name="mediaTypes">
	  <map>
		  <entry key="html" value="text/html"></entry>
		  <entry key="json" value="application/json"></entry>
		  <entry key="xml"  value="application/xml"></entry>
	  </map>
	</property>
	 <property name="viewResolvers">
		<list>
		  <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
			<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
			<property name="prefix" value="/WEB-INF/jsp/"></property>
			<property name="suffix" value=".jsp"></property>
		  </bean>
		</list>
	</property>
</bean>

Step 3) Add model classes I am writing 2 classes i.e. Users.java and User.java. These classes will be having JAXB annotations, which will be used by marshaller to convert them in appropriate xml or json formats. They are for example only and you can write your own classes.


package com.howtodoinjava.model;

import java.util.Collection;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="users")
@XmlAccessorType(XmlAccessType.NONE)
public class Users
{
	@XmlElement(name="user")
	private Collection<User> users;

	public Collection<User> getUsers() {
		return users;
	}

	public void setUsers(Collection<User> users) {
		this.users = users;
	}
}

Now write User.java.


package com.howtodoinjava.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="user")
@XmlAccessorType(XmlAccessType.NONE)
public class User {

	@XmlElement(name="first-name")
	private String firstName;

	@XmlElement(name="last-name")
	private String lastName;

	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
}

Step 4) Update the controller Our DemoController.java will modified to have REST specific annotations for path mappings in request parameters mappings. Also, we will specify the header attributes for request and response.


@Controller
@RequestMapping("/users")
public class DemoController
{
	@RequestMapping(method = RequestMethod.GET, value="/{id}", headers="Accept=*/*")
	public @ResponseBody User getUserById(@PathVariable String id)
	{
		User user = new User();
		user.setFirstName("john");
		user.setLastName("adward");
		return user;
	}

	@RequestMapping(method = RequestMethod.GET,  headers="Accept=*/*")
	public @ResponseBody Users getAllUsers()
	{
		User user1 = new User();
		user1.setFirstName("john");
		user1.setLastName("adward");

		User user2 = new User();
		user2.setFirstName("tom");
		user2.setLastName("hanks");

		Users users = new Users();
		users.setUsers(new ArrayList<User>());
		users.getUsers().add(user1);
		users.getUsers().add(user2);

		return users;
	}
}

Now lets re-deploy the application on tomcat and hit the URL on any REST client. I am using RESTClient. This is a firefox plugin for testing the RESTful webservices.

URL : http://localhost:8080/firstSpringApplication/users

http://localhost:8080/firstSpringApplication/users

URL : http://localhost:8080/firstSpringApplication/users/123

http://localhost:8080/firstSpringApplication/users/123

Download source code

Drop me a comment if it really helped you, or you have any query.

Happy Leaning !!

Lokesh

I have 7 Years of rich experience in java technology. This has only increased my hunger to learn more. In this blog, i will be writing on different topics occasionally, and would love to engage in some meaningful serious discussions with you folks.

You may also like...

17 Responses

  1. moez says:

    can you help me please if i create this rest webservice So i can apply with another client for example with client service in c# or not

  2. divya says:

    I have tried to follow all steps mentioned in the blog above. I still get the error “description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request “accept” headers.”. I am able to generate o/p in xml format, but I get this error while trying to generate the response in json format.

    • Lokesh says:

      You need to add dependency for “jackson-core-asl” as well.

      <dependency>
      <groupid>org.codehaus.jackson</groupid>
      <artifactid>jackson-core-asl</artifactid>
      <version>${jackson-core-asl.version}</version>
      <scope>runtime</scope>
      </dependency>

  3. Rakesh Nakod says:

    Tried adding “application/xml” as “accept” header in request header.Getting the following error.

    HTTP Status 406 -

    type Status report

    message

    description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request “accept” headers.

  4. Javier says:

    Great example!,

    I have a question, when I try to call the web service from another client (no local) I have the following message:

    “is not allowed by Access-Control-Allow-Origin”,

    But in the method header I see this code:

    @RequestMapping(method = RequestMethod.GET, value=”/{id}”, headers=”Accept=*/*”)

    What code Do I have to add over there?

    Thanks a lot!

    • Lokesh Gupta says:

      Probably you are accessing rest API from another application, that’s why you are seeing this problem. This is not REST implementation specific. It needs to be resolved at application configuration level.

      • Javier says:

        thanks, I have to configurate my app.
        Does your demo can send json parameters too? I tried to send it like jersey (@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) but it doesn’t work.

        Thanks a lot, I just discovered your blog.

  5. Vinod says:

    Hi Lokesh,
    Your blog is awesome and it is really helpful….Thanks alot

  6. Balaji says:

    How to use

    all
    as of now response is there in xml…

    • howtodoinjava says:

      Hi Bala, if you see the very first image, i have passed “application/xml” as “accept” header in request. So, the returned response is in xml.
      If you want to get response in json, then send the accept header as “applicatio/json”. The same goes for html also.

Note:- In comment box, please put your code inside [java] ... [/java] OR [xml] ... [/xml] tags otherwise it may not appear/post as intended.


Want to ask any question? Or suggest anything?