Sunday, September 14, 2014

RESTfull web services with Spring Boot and Jersey

Please bare with me and excuse me if there are any mistakes in following tutorial, it is my firstborn :)

In this tutorial I will show how to create a new Java project from scratch and integrate Spring Boot and Jersey using maven into it.
Jersey RESTful Web Services framework is open source, production quality, framework for developing RESTful Web Services in Java that provides support for JAX-RS APIs and serves as a JAX-RS (JSR 311 & JSR 339) Reference Implementation.

Also this project will be used in further tutorials where I will discuss and explain various technologies which can be used across single application. 

Completed project can be found on github.


Technologies:

  1. Java 8
  2. InteliJ
  3. Maven 3
  4. Spring Boot 1.1.6.RELEASE
  5. Jersey 2.7

Create empty project with all necessary dependencies

Following screens will show how to create empty project with maven module. By adding maven module into empty project, well known pom.xml will be generated among with project structure.





After creating new maven project, pom.xml file should look like :
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.discount</groupid>
    <artifactid>discount-rest-services</artifactid>
    <version>1.0-SNAPSHOT</version>
</project>

Now Spring and Jersey needs to be added, but also we need to integrate JSON framework into Jersey which will do JSON-to-Java binding and in this case I will use Jackson

pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.discount</groupid>
    <artifactid>discount-rest-service</artifactid>
    <version>0.1.0</version>

    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>1.1.6.RELEASE</version>
    </parent>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
            <version>1.1.6.RELEASE</version>
        </dependency>

        <!-- End Spring -->

        <!-- Jackson -->
        <dependency>
            <groupid>com.fasterxml.jackson.jaxrs</groupid>
            <artifactid>jackson-jaxrs-json-provider</artifactid>
            <version>2.4.2</version>
        </dependency>
        <!-- End Jackson -->

        <!-- Jersey -->
        <dependency>
            <groupid>org.glassfish.jersey.containers</groupid>
            <artifactid>jersey-container-servlet</artifactid>
            <version>2.7</version>
        </dependency>
        <!-- End Jersey -->
    </dependencies>

    <properties>
        <start-class>com.discount.Application</start-class>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>
</project>
After that run the following command under the project location path: 

mvn clean package

If you look in the target directory you should see discount-rest-services-1.0-SNAPSHOT.jar.  spring-boot-maven-plugin plugin is responsible for creating this executable jar file, which allows us to run the application in production.  Executable jars (sometimes called “fat jars”) are archives containing your compiled classes along with all of the jar dependencies that your code needs to run. 

Create Resources and Representation layers

Since this demo application is about discounted products, we will need Product representation and properties like id, name, regularPrice, discountPrice and currency. So under java folder create following packages, com.discount.representation and com.discount.resources. 

Folder structure should look like:




Inside representations package add new java class called Product.java with above mentioned properties, getters, setters and constructor.

Product.java
package com.discount.representations;

public class Product {
    private Long id;
    private String name;
    private String currency;
    private Double regularPrice;
    private Double discountPrice;

    public Product(Long id, String name, String currency, Double regularPrice, Double discountPrice) {
        this.id = id;
        this.name = name;
        this.currency = currency;
        this.regularPrice = regularPrice;
        this.discountPrice = discountPrice;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Double getRegularPrice() {
        return regularPrice;
    }

    public void setRegularPrice(Double regularPrice) {
        this.regularPrice = regularPrice;
    }

    public Double getDiscountPrice() {
        return discountPrice;
    }

    public void setDiscountPrice(Double discountPrice) {
        this.discountPrice = discountPrice;
    }

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }
}

Under resources package add new java class called ProductsResource.java

ProductsResource.java
package com.discount.resources;

import com.discount.representations.Product;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;


@Path("/products")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ProductsResource {

    @GET
    public List getAll(){
        List products = new ArrayList();
        products.add(new Product(1L, "iPhone 6", "USD", 850D, 750D));
        return products;
    }

    @GET
    @Path("{id}")
    public Product getOne(@PathParam("id")Long id){
        if(id == 888){
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }else {
            return new Product(id, "iPhone 6", "USD", 850D, 750D);
        }
    }
}

All resource classes are annotated with @Path or at least one method inside class with  a request method generator such as @GET, @POST, @PUT, @DELETE and with @Path.

Those annotations comes from JAX-RS which is Java API designed to help creating REST services. More about JAX-RS annotations can be found on official Java documentation.


Set up Spring and run the application

Now we need to tell Spring to scan and register our resource class so we can access it. But first we will create a class which will inherit resource configuration class which is main class for configuring a web application and add all resources under resources package. Under com.discount package we will create new package called config and add new class JerseyInitialization.java

JerseyInitialization.java
package com.discount.config;

import org.glassfish.jersey.server.ResourceConfig;

public class JerseyInitialization extends ResourceConfig {
    /**
     * Register JAX-RS application components.
     */
    public JerseyInitialization(){
        this.packages("com.discount.resources");
    }
}


Under com.discount package add new class, Application.java

Application.java
package com.discount;
import com.discount.config.JerseyInitialization;
import org.glassfish.jersey.servlet.ServletContainer;
import org.glassfish.jersey.servlet.ServletProperties;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;

@EnableAutoConfiguration
public class Application {
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).run(args);
    }

    @Bean
    public ServletRegistrationBean jerseyServlet() {
        ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/*");
        registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyInitialization.class.getName());
        return registration;
    }
}
@EnableAutoConfiguration annotation tells Spring Boot to “guess” how you will want to configure Spring, based on the jar dependencies that you have added. Since spring-boot-starter-web added Tomcat and Spring MVC, the auto-configuration will assume that you are developing a web application and setup Spring accordingly. Finally we will inject all our jersey resources into servlet and we should be good to go. 

In command prompt type:


mvn clean package && java -jar target/discount-rest-services-1.0-SNAPSHOT.jar

After successful build and spring boot have started the application you can try visiting http://localhost:8080/products from your browser.


No comments:

Post a Comment