Building Restful Web Services

Building Restful Web Services with Spring

In the last post, we covered basic of REST API. This post will guide us through Building Restful Web Services with Spring. If you are starting your project, our recommendation is to use Spring Boot to build your Restful Web Services. In case you don’t have the option to use Spring Boot, just navigate to the second part of this post for using traditional way to of  Building Restful Web Services with Spring.

 

1. Build Restful Web Services using Spring Boot

There are multiple ways of creating REST services using Spring Boot. Here are the different options

  1. Spring Boot Initializr.
  2. Using Maven.
  3. IDE of your choice.

What you will need

  • IDE
  • JDK 1.8 or later
  • Maven (You can also opt for Gradle)

 

1.1 Spring Boot Initializr

This is the simplest way to build Spring Boot REST API.Open Spring Initializr in your browser.it will present you with a wizard to start your configurations.

Building an Application with Spring Boot

 

Fill out the relevant details in the wizard, add “Web” (We will add other required dependencies while we are working on our REST service series.) in the dependencies section and hit generate button.Spring Initializr will generate a base project, it will give you a zip to download. You can import the unzipped project as a simple maven/ gradle based project in your IDE. Refer to Creating a Web Application with Spring Boot for more detail.

 

1.2 Using Maven

I will not be covering how to create a simple project using Maven. Once you have simple Java project using Maven, we need to update pom.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javadevjournal</groupId>
    <artifactId>rest-service-series</artifactId>
    <version>0.1</version>
    <description>Build RESTful Webservices using Spring</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

     <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

     <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>   

   </project>

 

Most of the main work is being taken care by Spring Boot Maven Plugin

 

1.3 Using IDE

Most of the modern IDE provide direct support for building REST services using Spring Boot. I use IntelliJ IDEA but you can use Eclipse or even Spring Tool Suite (STS).

 

1.4 Resource Representation

We discussed basic principles of RESTfull API in our first articles What is REST API. A resource is one of the fundamental concepts of REST services. Basic project setup is complete, we can now start working on creating our REST web service.

We will work on a simple service interaction.

  • Service will handle GET request for /product with a productCode parameter in the query string.
  • Service should return 200 OK response with JSON (we will cover other formats in this series) data in the body which represents our product information.

This is how our JSON response will look like

 

{  
   "code":"K123456",
   "name":"Super Product",
   "description":"We build this product during our REST service course",
   "price":100.00
}

We will now create resource representation class for the product.This will be plain old Java object

package com.javadevjournal.rest.model;

public class Product {

    private String code;
    private String name;
    private String description;
    private double price;

    public Product() {
    }

    public Product(String code, String name, String description, double price) {
        this.code = code;
        this.name = name;
        this.description = description;
        this.price = price;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

As part of the next step, we will create our first resource controller which will handle REST request and will send the response in JSON format.

REST Controller
package com.javadevjournal.rest.controller;

import com.javadevjournal.rest.controller.service.ProductService;
import com.javadevjournal.rest.model.Product;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
class ProductController {

    @Autowired
    ProductService productService;

    @RequestMapping("/product")
    public @ResponseBody
    Product getProduct(@RequestParam(value = "code") String productCode) {

        return productService.getProductByCode(productCode);
    }
}
Service Class
package com.javadevjournal.rest.controller.service;

import com.javadevjournal.rest.model.Product;

import org.springframework.stereotype.Service;

@Service("productService")
public class ProductService {

    public Product getProductByCode(final String productCode){

        Product product = new Product();
        product.setCode(productCode);
        product.setName("Super Product");
        product.setDescription("We build this product during our REST service course");
        product.setPrice(100.00);

        return product;
    }
}

This is the first example of our REST web service API. Our controller is simple but there are multiple things going on under the hood.

  • @RequestMapping annotation ensures that request to /product is mapped to the getProduct method.
  • We need to pass product code to the method, @RequestParam is responsible to bind query string parameter to code.
  • getProduct() method call getProductByCode() which creates Product and fills sample data.
  • The code is using @RestControler annotation (not @Controller annotation) which was introduced in Spring 4.
  • One of the main features of @RestController annotation is its ability to return domain object for every method call and not a view.
  • @RestController is a combination of @Controller and @ResponseBody annotation together.
  • The @ResponseBody annotation tells Spring MVC to write return object in the response and not use the view.
  • Product data needs to be converted to JSON, this is automatically taken care by Spring’s HTTP message converter support.
  • We used Spring Boot to bootstrap our REST web service, it automatically added Jackson 2 to the classpath. Spring’s MappingJackson2HttpMessageConvertor will automatically handle conversion of Product to JSON.

 

There are few key points which differentiate our REST controller from a conventional controller which is responsible for returning a view.

 

  • We are not returning any view from our controller but returning actual domain object (Product in our case).
  • This Product data will be written directly in the response as JSON, XML or YAML format (JSON in our example).

 

 

1.5 Run Application

We will run our application by using SpringApplication helper class from Spring Boot.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RestServiceSeriesApplication {

	public static void main(String[] args) {
		SpringApplication.run(RestServiceSeriesApplication.class, args);
	}
}

Once our service is up and running, visit  http://localhost:8080/product?code=KI03811 and you should be able to see

{
code: "KI03811",
name: "Super Product",
description: "We build this product during our REST service course",
price: 100
}

We have created and deployed a REST web service with Spring Boot.

 

 

2. Build Restful Web Services using Spring MVC (Not Spring Boot)

In this section, we will cover how to create REST web services using Spring. There is still a possibility that you are not using Spring Boot for your project. We will discuss the process to Bootstrap a Web Application with Spring.

 

2.1 Create Simple Web Application using Maven

We will use Maven to create a simple web module, once the module is created by Maven, we will start expanding our application for supporting our REST web service. You can use IntelliJ IDEA, Eclipse or any other IDE to create web module using Maven. (We will not be covering project creation in this post).

 

2.2 Maven pom.xml

Once our web module is created, we need to add required Spring MVC dependencies for out REST module. 

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.javadevjournal</groupId>
    <artifactId>restserviceseries</artifactId>
    <packaging>war</packaging>
    <version>01.-SNAPSHOT</version>
    <name>rest-service-series Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <spring.version>4.3.13.RELEASE</spring.version>
        <jackson-version>2.9.0</jackson-version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson-version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
        <finalName>rest-service-series</finalName>
    </build>
</project>

 

2.3  Java based Web Configurations

Let’s create our Spring MVC configuration which will provide startup configurations for our web application. I will not be covering XML based configuration but you can find several example on the net (if you prefer)

package com.javadevjournal.rest.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.javadevjournal.rest"})
public class AppConfig {

    // required configurations
}

Let’s look at our example in details to understand different aspects of it.

The @Configuration annotation is the central artifact of Spring’s Java-configurations.@Configuration is a meta-annotated as a @Component which make is eligible for component scanning, it also gives the flexibility to use @Autowired annotations. A class annotated with @Configuration annotation shows that this can be used by Spring IoC container for bean definitions.

@EnableWebMvc annotation to an @Configuration class will imports Spring MVC configurations from WebMvcConfigurationSupport. In simple terms, it will register several Spring MVC infrastructure beans which are needed for MVC application (e.g  Data / Payload converter etc). If you are familiar with XML based configurations, it is equivalent to <mvc:annotation-driven/>.

@ComponentScan annotation with @Configuration classes class provides support parallel with Spring XML’s <context:component-scan> element. This will enable Spring to scan all classes through the package and will register all beans and controller for our application.

 

2.4  The DispatcherServlet

With Servlet 3.0, we can define our container configurations without the web.xml file. Read Spring WebApplicationInitializer to get understand the Java-based configuration.

package com.javadevjournal.rest.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class CustomWebAppInitializer implements WebApplicationInitializer {
    /**
     * Configure the given {@link ServletContext} with any servlets, filters, listeners
     * context-params and attributes necessary for initializing this web application. See examples
     * {@linkplain WebApplicationInitializer above}.
     *
     * @param servletContext the {@code ServletContext} to initialize
     * @throws ServletException if any call against the given {@code ServletContext} throws a {@code
     *                          ServletException}
     */
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);

        // Manage the lifecycle of the root application context
        servletContext.addListener(new ContextLoaderListener(rootContext));

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher =
                servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

 

2.5  REST Controller

Our infrastructure is ready, let’s create our REST Controller, which will return Product in the response. For more details about REST controller structure and representation, please refer to section1.

@RestController
class ProductController {

    @RequestMapping("/product")
    public @ResponseBody
    Product getProduct(@RequestParam(value = "code") String productCode) {

        return getProductByCode(productCode);
    }

    private Product getProductByCode(final String productCode){

        Product product = new Product();
        product.setCode(productCode);
        product.setName("Super Product");
        product.setDescription("We build this product during our REST service course");
        product.setPrice(100.00);

        return product;
    }
}

 

2.6  Run Application 

Build and deploy your application.Once our service is up and running, visit  http://localhost:8080/product?code=KI03811 and you should be able to see

{
code: "KI03811",
name: "Super Product",
description: "We build this product during our REST service course",
price: 100
}

We have created and deployed a REST web service with Spring.

 

Summary

In this article on REST with Spring, we covered how to create REST web service using Spring Boot and Spring MVC. Read about some basics of building REST API using Spring.

Comments are closed.