Spring MVC 4.0 RESTFul Web Services Simple Example




REST(Representational State Transfer) is an architectural style with which Web Services can be designed that serves resources based on the request from client. A Web Service is a unit of managed code, that can be invoked using HTTP requests. Let me put it simple for those who are new to Web Service.You develop the core functionality of your application, deploy it in a server and expose to the network. Once it is exposed, it can be accessed using URI's through HTTP requests from a variety of client applications. Instead of repeating the same functionality in multiple client (web, desktop and mobile) applications, you write it once and access it in all the applications. 


Spring MVC & REST

Spring MVC supports REST from version 3.0. It is easier to build restful web services with spring with it's annotation based MVC Framework. In this post, I am going to explain how to build a simple RESTFul web service using Spring MVC 4.0, that would return plain text.

Now, take a look at the architecture diagram above to understand how spring mvc restful web service handles requests from client. The request process flow is as follows,

1. Client application issues request to web service in the form of URI's.

         Example: http://example.com/service/greetings/Priya


2. All HTTP Requests are intercepted by DispatcherServlet (Front End Controller). - This is defined in the web.xml file.

3. DispatcherServlet looks for Handler Mappings. Spring MVC supports three different ways of mapping request URI's to controllers : annotation, name conventions and explicit mappings. Handler Mappings section defined in the application context file, tells DispatcherServlet which strategy to use to find controllers based on the incoming request. More information on Handler Mappings can be found here.

4. Requests are now processed by the Controller and response is returned to DispatcherServlet. DispatcherServlet looks for View Resolver section in the application context file. For RESTFul web services, where your web controller returns ModelAndView object or view names, 'ContentNegotiatingResolver' is used to find the correct data representation format.

5. There is also an alternate option to the above step. Instead of forwarding ModelAndView object from Controller, you can directly return data from Controller using @ResponseBody annotation as depicted below. You can find more information on using ContentNegotiatingResolver or ResponseBody annotation to return response here.





Its time to get our hands dirty with some real coding. Follow the steps below one by one to get your first Spring MVC REST web service up and running.

1. Download Spring MVC 4.0 jar files from this maven repository here.

2. Create Dynamic Web Project and add the libraries you downloaded to WEB-INF/lib folder.


3. Open /WEB-INF/web.xml file and add below configuration before </webapp> tag.


<servlet>
 <servlet-name>rest</servlet-name>
 <servlet-class>
  org.springframework.web.servlet.DispatcherServlet
 </servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
 <servlet-name>rest</servlet-name>
 <url-pattern>/*</url-pattern>
</servlet-mapping>

Note that in the above code,we have named Spring Dispatcher servlet class as "rest" and the url pattern is given as "/*" which means any uri with the root of this web application will call DispatcherServlet. So what's next? DispatcherServlet will look for configuration files following this naming convention - [servlet-name]-servlet.xml. In this example, I have named dispatcher servlet class as "rest" and hence it will look for file named 'rest-servlet.xml'.

4. Now create an xml file under WEB-INF folder and name it 'rest-servlet.xml'. Copy the below in it.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
 <context:component-scan base-package="com.programmingfree.springservice.controller" />
 <mvc:annotation-driven />
  </beans>


With ComponentScan tag, Spring auto scans all elements in the provided base package and all its child packages for Controller servlet. Also, we have used <mvc:annotation-driven> tag instead of ViewResolver, with which we can directly send response data from the controller.

5. Let us create a controller servlet in the package mentioned in the component-scan tag. Copy and paste the below code in it.

package com.programmingfree.springservice.controller;


import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/service/greeting")
public class SpringServiceController {
 @RequestMapping(value = "/{name}", method = RequestMethod.GET)
 public String getGreeting(@PathVariable String name) {
  String result="Hello "+name;  
  return result;
 }
}


'@RequestMapping' annotation is used for defining incoming request urls for class and method levels. In this case all uri's in the format <root-url>/service/greeting/ will be routed to this Controller class. With @RequestMapping annotation, we can only define generic uri mappings. For dynamic uri mappings in case of passing variables along with the uri, @PathVariable is used. Here in this case, we pass a variable 'name' along with the uri such as, <root-url>/service/greeting/Priya. Here the last parameter (Priya) in the uri is retrieved using @PathVariable.

I explained that while using <mvc:annotation-config> tag instead of view resolver, we use '@ResponseBody' annotation to return response data directly from controller. But in the above code, I have not used '@ResponseBody'. This is because, in Spring MVC 4.0, they have introduced '@RestController' such that we need not use '@ResponseBody' tag in each and every method. '@RestController' will handle all of that at the type level.

This annotation simplifies the controller and it has '@Controller' and '@ResponseBody' annotated within itself.

Let us take a look at the same controller but with Spring MVC 3.0,

@Controller
@RequestMapping("/service/greeting")
public class SpringServiceController {
 @RequestMapping(value = "/{name}", method = RequestMethod.GET)
 public @ResponseBody String getGreeting(@PathVariable String name) {
  String result="Hello "+name;  
  return result;
 }
}

Note that in Spring MVC 3.0 we had to expicitly use @Controller annotation to specify controller servlet and @ResponseBody annotation in each and every method. With the introduction of '@RestController' annotation in Spring MVC 4.0, we can use it in place of @Controller and @ResponseBody annotation.


That is all! Simple RESTFul Web Service returning greeting message based on the name passed in the URI, is built using Spring MVC 4.0.

So now run this application in Apache Tomcat Web Server.

Open Web Browser, and hit this url, 'http://localhost:8080/<your-application-name>/service/greeting/<anyname> . If you have downloaded this sample application, then use,
http://localhost:8080/SpringServiceSample/service/greeting/Priya . You will be seeing greeting message sent as response from server,






Keep yourself subscribed to programming-free.com to get these articles delivered to your inbox. Thanks for reading!


Subscribe to GET LATEST ARTICLES!


advertise here

Related

Spring MVC 206126835587078576

Post a Comment

  1. Good post. However, I believe, the reason why viewresolver is not a correct option from a service perspective, is because, a webservice is typically consumed by applications rather than a browser, where a view need to be rendered. So, @ResponseBody is better suited for a service, a view resolver for web application

    ReplyDelete
    Replies
    1. I agree. At the end it all depends upon the application requirements whether it requires raw response or a view with html or jsp to be returned by the service. It is always better to stick to @ResponseBody to support multiple front end applications developed on a variety of platforms.

      Delete
  2. Good post, what about produces=(MimeTypeUtils.APPLICATION_JSON_VALUE), if you don't add produces then content type wouldn't be set to application/json.

    ReplyDelete
    Replies
    1. This example just tries to return plain text and does not return json. The idea is to explain how a basic Spring MVC RESTFul Web Service application should be implemented. In my upcoming post I am going to explain in detail on how to make Spring MVC RestFul Web Service to return response in JSON format. Stay tuned.

      Delete
  3. Hi Priya how can I return Media Type as a XML with your current implementation.

    ReplyDelete
  4. HI Priya,

    I downloaded your example, run it :
    http://localhost:8080/SpringServiceSample/service/greeting/Majid

    I got an error :

    HTTP Status 404 - /SpringServiceSample/service/greeting/Majid
    --------------------------------------------------------------------------------
    type Status report
    message /SpringServiceSample/service/greeting/Majid
    description The requested resource is not available.
    Apache Tomcat/7.0.47

    Thanks, your help is appreciated.

    ReplyDelete
    Replies
    1. Check whether application is deployed properly in Tomcat. Clean tomcat work directory and publish from the beginning.

      Thanks,
      Priya

      Delete
  5. Hi Priya ,

    I downloaded your application and trying to run in tomcat 7 wiht jdk 7 .But I am unable to run and getting the same error as mentioned above i.e 404 .

    I can see the application in server section in Eclipse but not in webapps folder of tomcat .

    Help is appreciated.

    Thanks

    ReplyDelete
  6. Nice article !
    I am new to web services and pretty confused that you have not mention about the jar required for web services implemetaiin, I mean which implementation of rest here have been used. Please answer me. opcs001@gmail.com

    ReplyDelete
    Replies
    1. Really ??? Take a look at point no 1 which gives the exact location from where you can download the jars and point no 2 which explains where exactly you have to place your jars. And by the way if you had read atleast the title of this article, I am sure you would have known that I had explained about Spring MVC Framework's RESTFul Web Services.

      Hope this helps!

      Delete
    2. Just to clarify: you mean web service specification is JAX-RS with its implementation provided by spring mvc itself rather than apache axis 2 or cxf. Sorry to ask again but I am really confused. For axis 2 we use some jar with name like axis_2.jar, is this inbuilt in spring itself. Thank you :)

      Delete
  7. HTTP Status 404 - /SpringServiceJsonSample/

    --------------------------------------------------------------------------------

    type Status report

    message /SpringServiceJsonSample/

    description The requested resource (/SpringServiceJsonSample/) is not available.

    I have tried with cleaning apache work directry too ..but error pressist

    ReplyDelete
    Replies
    1. Can you provide the url you tried to hit? It wont work until you give this,

      http://localhost:8080/SpringServiceSample/service/greeting/somename

      We have defined our service to map to the above path /SpringServiceSample/service/greeting/somename

      Thanks,
      Priya

      Delete
  8. @RestController is used as class level annotation so what if i want to render ModelView from one of the method from our class and @ResponseBody from another method of the same class.Will it work if we do so?is it legal?

    ReplyDelete
  9. I have a requirement, i need to create 2 webapps. Webapp1 is basically handling UI of the project and creating users for application. Webapp2 is the one which will do all the working part with separate DB, now i need to use restful web services. Obviously webapp1 is acting client and webapp2 is acting server. Now how will a send request from client to server. Do you have an example for that? (Webapp1 and 2 needs to be totally isolated/independent because of security reasons, that's why i have this kind of requirement)

    ReplyDelete
  10. I think there's a little inconvenient when doing RESTful WSs this way. If you want to transfer your own classes you need to share those classes between the two projects. And for that you need to create another project (jar) and use it in both apps.

    ReplyDelete
  11. Hi,
    Thanks for the interesting article and your narration is so clear to understand the stuff.

    I downloaded your code and hit the exact URL which matches the controller URL but it dint work for me.
    Spring 4.0.1 version the source code did not work for me on tomcat 7, eclipse juno SR2, Java 5 u22.
    Following error is seen.
    HTTP Status 404 - /SpringServiceSample/service/greeting/kumar
    --------------------------------------------------------------------------------
    type Status report
    message /SpringServiceSample/service/greeting/somename
    description The requested resource is not available.


    Could not debug as the request not reaching the servlet itself. Please kindly let me know if any
    other configuration need to be done to make it work. Even the other json REST code also same issue is observed. Please help.

    Thanks,
    Kumar

    ReplyDelete
    Replies
    1. Well,since many reported that this project does not work as expected, I downloaded it myself in a different PC to see what is the issue. If you closely look into your Tomcat startup console log,you would see this WARNING message,

      WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server: SpringServiceSample' did not find a matching property.

      To resolve this in eclipse,

      Open servers tab.
      Double click on the server you are using.
      On the server configuration page go to server options page.
      Check Serve module without publishing.
      Then save the page and configurations.
      Restart the server and rebuild all the applications.

      It worked for me after this. Basically it means, that Tomcat does not know what to do with the source attribute from context. This source attribute is set by Eclipse (or to be more specific the Eclipse Web Tools Platform) to the server.xml file of Tomcat to match the running application to a project in workspace. Tomcat generates a warning for every unknown markup in the server.xml (i.e. the source attribute) and this is the source of the warning.

      Let me know whether this fixed your issue. I will update my post as well, with this solution soon.

      Thanks,
      Priya

      Delete
  12. It is crystal clear...thanks for the post...

    ReplyDelete
    Replies
    1. Can you also explain best way to provide security for the RESTful web services other than role based and https.

      Delete
    2. I will try for sure and thanks for the feedback.

      Delete
  13. Thanks for explaining @RestController annotation. It was useful. Regards

    ReplyDelete

emo-but-icon

Currency Converter

Built using AngularJS and ASP.NET Web API

SUBSCRIBE


item