Wednesday, January 20, 2016

How to Write a RESTful Web-Service Using the Spring Web MVC Framework

In the article I would like describe how to write a RESTful web-service using the Spring Web MVC framework and no line of XML (except the pom.xml file). Also, WebSphere Liberty Profile will be leveraged for testing and running the RESTful web-service. The code of the example is hosted on GitHub.


Architecture


The main purpose of the example is to show how to implement the classic multilevel enterprise application architecture that is implemented by almost applications built on the Spring Framework. The entry point for the example is a MVController MessageController, which has a number of injection points for the MessageService and ZShopService services:


Each service also contains an injection point for a "resource", i.e. an instance of the TextResource class. The resources look like as primitive data access objects (DAOs):


The @Autowired annotation is used for dependencies management in the controller and the services. If it is required to develop some unit tests for the application classes, the defined in every class public setters will be used for mock injection.

Controller


A controller is responsible for a communication process with a client. This component gets an HTTP request with a defined method (GET, PUT, POST, DELETE, etc.) and some constraints (Accept: ...), extracts request parameters, calls a model and gets a result from the model, transform the result to the requested format and returns it to the client. The main part of this job is delegated to the Spring Web MVC framework, application developers only have to declarative, using Java annotations, define their expectations, the request paths to controller methods mapping, and set the actual representation format for a response.

Because the RESTful web-service is being developed, results returned by the controller methods are not a ModelAndView instance, but just response bodies, the @RestController annotation is used for the controller class registration in the Spring Web MVC framework.

In the application, the controller contains three methods: textMessage(), jsonMessage(), and xmlMessage(). Every method is mapped on the common request path '/api/message' and is dispatched by the 'Accept' HTTP header. The 'produces' parameter of the @RequestMapping annotation is used for setup this behavior.


How to setup the Spring Application Context


In the application Java-configuration for the Spring Framework is used. For ensure successful application start, the following actions have to be done: to register the DispatcherServlet into the application server, configure the '/api/' request-path mapping for the servlet, and register the ContextLoaderListener listener that loads the Spring application context. The ApplicationInitializer class contains some code for these actions.


In the first line of the onStartup() method the Spring Web MVC configuration class is being registered. The class might be a subclass of the WebMvcConfigureAdapter class and overload it's methods for the framework customization.


The @ComponentScan annotation defines a Java package for dependencies scanning, while the @EnableWebMvc one tells the configuration has to be inherited from the WebMvcConfigurationSupport class.

Application deployment and testing


The sipped with the application pom.xml file contains a configuration for WebSphere Liberty Profile. So, only four simple steps should be done for the building, deployment and running of the application:

  1. Execute full Maven build.

    $ mvn clean package

  2. Load WebSphere Liberty Profile kernel from the repository. The kernel archive contains just 11 MB (it is only 1.5 more than Apache Tomcat 8.0.30 does).

    $ mvn liberty:create-server

  3. Install the only one feature needed for running the application.

    $ mvn liberty:install-feature

  4. Run the server with the example.

    $ mvn liberty:run-server

    Once the server is running, the application will be available under http://localhost:9082/rest-web-service/api/message.

Now, the controller can be invoked just using the following code snippet (Jersey 2 is needed):


A result looks like the following:


Would you like to give a 'Like'? Please follow me on Twitter!