Java Servlet RESTFul client

In Java Servlet RESTFul client tutorial, we create a RESTFul client in a Java Servlet with JAX-RS.

Java API for RESTful Web Services (JAX-RS) is a Java API specification that provides support in creating web services according to the Representational State Transfer (REST) architectural pattern.

Jersey is a Java RESTful Web Services Framework and a JAX-RS Reference Implementation.

Servlet is a Java class which responds to a particular type of network request - most commonly an HTTP request. Java servlets are used to create web applications. They run in servlet containers such as Tomcat or Jetty. Modern-day Java web development uses frameworks that are built on top of servlets.

Java Servlet application

The following web application creates a request to the api.randomuser.me site, which is a random user generator.

The Java servlet uses ClientBuilder to create a Client, which is the main entry point to the fluent API used to build and execute client requests in order to consume responses returned.

$ tree
.
├── nb-configuration.xml
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── zetcode
    │   │           ├── model
    │   │           │   ├── Location.java
    │   │           │   ├── Name.java
    │   │           │   ├── Person.java
    │   │           │   └── PersonsList.java
    │   │           ├── service
    │   │           │   └── PersonService.java
    │   │           └── web
    │   │               └── MyServlet.java
    │   ├── resources
    │   └── webapp
    │       ├── index.html
    │       ├── META-INF
    │       │   └── context.xml
    │       ├── show.jsp
    │       └── WEB-INF
    └── test
        └── java

This is the project structure.

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.zetcode</groupId>
    <artifactId>JavaServletRestClient</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>JavaServletRestClient</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>           
        
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.25.1</version>
        </dependency>      
        
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.22</version>
        </dependency>            
        
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

This is the Maven POM file. We have four artifacts: javax.servlet-api for servlets, jstl for the standard JSP tags library, the jersey-client for the RESTFul core client implementation and the jersey-media-json-jackson for JSON/Java Bean data binding.

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JavaServletRestClient"/>

In the Tomcat context.xml file, we define the context path. It is the name of the web application.

In the application, we have three beans; these beans will be filled with data from the response.

Location.java
package com.zetcode.model;

public class Location {

    private String street;
    private String city;
    private String state;
    private String postcode;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getPostcode() {
        return postcode;
    }

    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();
        sb.append(street).append(" ")
                .append(city).append(" ")
                .append(state).append(" ")
                .append(postcode);
        return sb.toString();
    }
}

The Location stores the address of the user.

Name.java
package com.zetcode.model;

public class Name {

    private String first;
    private String last;
    private String title;

    public String getFirst() {
        return first;
    }

    public void setFirst(String firstName) {
        first = firstName;
    }

    public String getLast() {
        return last;
    }

    public void setLast(String lastName) {
        last = lastName;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
    
    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();
        sb.append(title).append(" ").append(first)
                .append(" ").append(last);
        return sb.toString();
    } 
}

The Name stores the user name details.

Person.java
package com.zetcode.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {

    private Name name;
    private Location location;
    private String email;
    private String gender;

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

    public Name getName() {
        return name;
    }    

    public Location getLocation() {
        return location;
    }

    public void setLocation(Location location) {
        this.location = location;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();
        sb.append("Name: ").append(name)
                .append("Address: ").append(location)
                .append("Email ").append(email)
                .append("Gender: ").append(gender);
        return sb.toString();
    }
}

The Person class stores data about the user, including name, address, email, and gender.

@JsonIgnoreProperties(ignoreUnknown = true)

With the @JsonIgnoreProperties annotation we tell the Jackson to ignore properties not listed in the Person.

PersonsList.java
package com.zetcode.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class PersonsList {

    List<Person> results;

    public List<Person> getResults() {
        return results;
    }

    public void setResults(List<Person> result) {
        results = result;
    }
}

This is the list of Person objects. The web service fills this list with data.

MyServlet.java
package com.zetcode.web;

import com.zetcode.model.Person;
import com.zetcode.service.PersonService;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");

        List<Person> people = PersonService.fetchPeople(0, 50);

        request.setAttribute("people", people);
        request.getRequestDispatcher("show.jsp").forward(request, response);
    }
}

The MyServlet servlet calls the PersonService.fetchPeople(), which returns a list of Person objects. The list is stored as an attribute and the processing is dispatched to the show.jsp page. The JSP page renders the list of Person objects.

PersonService.java
package com.zetcode.service;

import com.zetcode.model.Person;
import com.zetcode.model.PersonsList;
import java.util.List;

import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;

public class PersonService {

    private static WebTarget resource = ClientBuilder.newBuilder()
            .build().target("https://api.randomuser.me/");
 
    public static List<Person> fetchPeople(int offset, int num) {
        PersonsList res = resource.queryParam("seed", 1)
                .queryParam("results", num).queryParam("page", 1)
                .request(MediaType.APPLICATION_JSON).get(PersonsList.class);
        return res.getResults();
    }      
}

PersonService contains a fetchPeople() method to perform a query on api.randomuser.me web service. The service returns randomly user objects.

private static WebTarget resource = ClientBuilder.newBuilder()
        .build().target("https://api.randomuser.me/");

With the ClientBuilder, we create a web resource target. The api.randomuser.me website returns randomly a list of users.

public static List<Person> fetchPeople(int offset, int num) {
    PersonsList res = resource.queryParam("seed", 1)
            .queryParam("results", num).queryParam("page", 1)
            .request(MediaType.APPLICATION_JSON).get(PersonsList.class);
    return res.getResults();
}    

We send a query to the web resouce; the data is stored in PersonsList.

index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Home Page</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <a href="MyServlet">List people</a>
    </body>
</html>

This is the home page. It contains a link to call the MyServlet.

show.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Show people</title>
    </head>
    <body>
        <table>
            <thead>
                <tr>
                    <th>Title</th>
                    <th>First name</th>
                    <th>Last name</th>
                    <th>Street</th>
                    <th>City</th>
                    <th>State</th>
                    <th>Postcode</th>
                    <th>Email</th>
                    <th>Gender</th>
                </tr>
            </thead>
            <tbody>

                <c:forEach var="per" items="${people}">
                    <tr>
                        <td><c:out value="${per.name.title}"/></td>
                        <td><c:out value="${per.name.first}"/></td>
                        <td><c:out value="${per.name.last}"/></td>
                        <td><c:out value="${per.location.street}"/></td>
                        <td><c:out value="${per.location.city}"/></td>
                        <td><c:out value="${per.location.state}"/></td>
                        <td><c:out value="${per.location.postcode}"/></td>
                        <td><c:out value="${per.email}"/></td>
                        <td><c:out value="${per.gender}"/></td>
                    </tr>
                </c:forEach>
            </tbody>
        </table>
    </body>    
</html>

The show.jsp page displays data in a HTML table using c:forEach and c:out tags from the JSTL library.

In this tutorial, we created a JAX-RS client request to a web service that generates randomly users. The request was sent from a Java servlet.

You might also be interested in the following related tutorials: Java servlet JSON tutorial, Java Servlet PDF tutorial, Java servlet check box tutorial, Java servlet image tutorial, Java Servlet HTTP headers, or Java tutorial.