Java Servlet RESTFul client
last modified August 24, 2023
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.
RESTEasy is a Java RESTful Web Services Framework and a JAX-RS implementation from JBoss.
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.
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 │ └── show.jsp └── test └── java
This is the project structure.
<?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> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>14</maven.compiler.source> <maven.compiler.target>14</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-servlet-initializer</artifactId> <version>4.5.5.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> <version>4.5.5.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> <version>4.5.5.Final</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.0</version> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.4.30.v20200611</version> </plugin> </plugins> </build> </project>
This is the Maven POM file. We have the following artifacts: javax.servlet-api
for servlets, jstl
for the standard JSP tags library,
resteasy-servlet-initializer
for integrating RESTEasy with servlets,
resteasy-client
for the RESTFul core client implementation
and resteasy-jackson2-provide
for JSON/Java model data binding.
In the application, we have three model classes; these models will be filled with data from the response.
package com.zetcode.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public class Location { private String city; private String state; private String postcode; 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() { final StringBuilder sb = new StringBuilder("Location{"); sb.append("city='").append(city).append('\''); sb.append(", state='").append(state).append('\''); sb.append(", postcode='").append(postcode).append('\''); sb.append('}'); return sb.toString(); } }
The Location
stores the address of the user.
@JsonIgnoreProperties(ignoreUnknown = true)
With the @JsonIgnoreProperties
annotation we tell the
Jackson to ignore properties not listed in the Person
.
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.
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.
package com.zetcode.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) public class PersonsList { private 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.
package com.zetcode.web; import com.zetcode.model.Person; import com.zetcode.service.PersonService; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @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.
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
.
<!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
.
<%@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>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.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.
$ mvn jetty:run
We start the application and locate to localhost:8080
.
In this article we created a RESTEasy client request to a web service that generates randomly users. The request was sent from a Java servlet.