Jersey 2 client API finds inspiration in the proprietary Jersey 1.x Client API. In this Jersey client example, we will learn to build client API and invoke different REST methods and consume the API results.
Table of Contents 1. Jersey Client Maven 2. Jersey ClientBuilder 3. HTTP GET - Collection/List of Entities 4. HTTP GET - Single Entity 5. HTTP POST 6. HTTP PUT 7. HTTP DELETE 8. Model classes and Configuration files
1. Jersey Client Maven
Add jersey client maven dependency in pom.xml
file.
<dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> <version>2.25.1</version> </dependency>
2. Jersey ClientBuilder
JAX-RS Client API is a designed to allow fluent programming model. To create jersey client follow these steps –
- Use
ClientBuilder.newClient()
static method. - Use client.target() method on above obtained client instance.
- Get
Invocation.Builder
usingwebTarget.request()
method on WebTarget instance obtained in second step. - Execute
invocationBuilder.get()
,put()
,post()
ordelete()
methods to invoke corresponding REST APIs.
Client client = ClientBuilder.newClient( new ClientConfig().register( LoggingFilter.class ) ); WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees"); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_XML); Response response = invocationBuilder.post(Entity.entity(emp, MediaType.APPLICATION_XML));
Given below examples will be able to help us get better understanding and set us up for development tasks. I will recommend to go through other Jersey examples such as file upload example and file download example.
3. HTTP GET – Collection/List of Entities
REST API
This is the API code written for retrieving all employees in the system.
@GET @Path("/employees") @Produces(MediaType.APPLICATION_XML) public Employees getAllEmployees() { Employees list = new Employees(); list.setEmployeeList(new ArrayList<Employee>()); list.getEmployeeList().add(new Employee(1, "Lokesh Gupta")); list.getEmployeeList().add(new Employee(2, "Alex Kolenchiskey")); list.getEmployeeList().add(new Employee(3, "David Kameron")); return list; }
Jersey Client Code
This RESTful client code will access above API and print the response in the console.
Client client = ClientBuilder.newClient( new ClientConfig().register( LoggingFilter.class ) ); WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees"); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_XML); Response response = invocationBuilder.get(); Employees employees = response.readEntity(Employees.class); List<Employee> listOfEmployees = employees.getEmployeeList(); System.out.println(response.getStatus()); System.out.println(Arrays.toString( listOfEmployees.toArray(new Employee[listOfEmployees.size()]) )); Output: 200 [Employee [id=1, name=Lokesh Gupta], Employee [id=2, name=Alex Kolenchiskey], Employee [id=3, name=David Kameron]]
4. HTTP GET – Single Entitiy
This is the API code written for retrieving single employee based on its id.
@GET @Path("/employees/{id}") @Produces(MediaType.APPLICATION_XML) public Response updateEmployeeById(@PathParam("id") Integer id) { if(id < 0){ return Response.noContent().build(); } Employee emp = new Employee(); emp.setId(id); emp.setName("Lokesh Gupta"); GenericEntity<Employee> entity = new GenericEntity<Employee>(emp, Employee.class); return Response.ok().entity(entity).build(); }
Client Code
This RESTful client code will access above API and print the response in the console.
Client client = ClientBuilder.newClient( new ClientConfig().register( LoggingFilter.class ) ); WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees").path("1"); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_XML); Response response = invocationBuilder.get(); Employee employee = response.readEntity(Employee.class); System.out.println(response.getStatus()); System.out.println(employee); Output: 200 Employee [id=1, name=Lokesh Gupta]
5. HTTP POST
This is the API code written for adding an employee in the collection.
@POST @Path("/employees") @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) public Response addEmployee( Employee e ) throws URISyntaxException { if(e == null){ return Response.status(400).entity("Please add employee details !!").build(); } if(e.getName() == null) { return Response.status(400).entity("Please provide the employee name !!").build(); } return Response.created(new URI("/rest/employees/"+e.getId())).build(); }
Jersey Client Code
This RESTful client code will access above API and print the response in the console.
Client client = ClientBuilder.newClient( new ClientConfig().register( LoggingFilter.class ) ); WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees"); Employee emp = new Employee(); emp.setId(1); emp.setName("David Feezor"); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_XML); Response response = invocationBuilder.post(Entity.entity(emp, MediaType.APPLICATION_XML)); System.out.println(response.getStatus()); System.out.println(response.readEntity(String.class)); Output: 201
6. HTTP PUT
This is the API code written for updating an employee name by its id.
@PUT @Path("/employees/{id}") @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) public Response updateEmployeeById(@PathParam("id") Integer id, Employee e) { Employee updatedEmployee = new Employee(); if(e.getName() == null) { return Response.status(400).entity("Please provide the employee name !!").build(); } updatedEmployee.setId(id); updatedEmployee.setName(e.getName()); return Response.ok().entity(updatedEmployee).build(); }
Jersey 2 Client Code
This RESTful client code will access above API and print the response in the console.
Client client = ClientBuilder.newClient( new ClientConfig().register( LoggingFilter.class ) ); WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees").path("1"); Employee emp = new Employee(); emp.setId(1); emp.setName("David Feezor"); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_XML); Response response = invocationBuilder.put(Entity.entity(emp, MediaType.APPLICATION_XML)); Employee employee = response.readEntity(Employee.class); System.out.println(response.getStatus()); System.out.println(employee); Output: 200 Employee [id=1, name=David Feezor]
7. HTTP DELETE
This is the API code written for removing an employee from the collection by id.
@DELETE @Path("/employees/{id}") public Response deleteEmployeeById(@PathParam("id") Integer id) { return Response.status(202).entity("Employee deleted successfully !!").build(); }
Jersey Client Code
This RESTful client code will access above API and print the response in the console.
Client client = ClientBuilder.newClient( new ClientConfig().register( LoggingFilter.class ) ); WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees").path("1"); Invocation.Builder invocationBuilder = webTarget.request(); Response response = invocationBuilder.delete(); System.out.println(response.getStatus()); System.out.println(response.readEntity(String.class)); Output: 202 Employee deleted successfully !!
8. Model classes and Configuration files
Listed below are other used files to create this Jersey 2 client example.
Employees.java
package com.howtodoinjava.jersey; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "employeeList") @XmlAccessorType (XmlAccessType.FIELD) public class Employees { @XmlElement(name="employee") private List<Employee> employeeList; public List<Employee> getEmployeeList() { return employeeList; } public void setEmployeeList(List<Employee> employeeList) { this.employeeList = employeeList; } }
Employee.java
package com.howtodoinjava.jersey; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "employee") @XmlAccessorType (XmlAccessType.FIELD) public class Employee { private Integer id; private String name; public Employee() { } public Employee(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + "]"; } }
pom.xml
<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.howtodoinjava.jersey</groupId> <artifactId>JerseyDemos</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <repositories> <repository> <id>maven2-repository.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> <layout>default</layout> </repository> </repositories> <properties> <jersey2.version>2.19</jersey2.version> <jaxrs.version>2.0.1</jaxrs.version> </properties> <dependencies> <!-- JAX-RS --> <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>${jaxrs.version}</version> </dependency> <!-- Jersey 2.19 --> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>${jersey2.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>${jersey2.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> <version>${jersey2.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>${jersey2.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-json-provider</artifactId> <version>2.4.1</version> </dependency> </dependencies> <build> <finalName>JerseyDemos</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>jersey-serlvet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.howtodoinjava.jersey</param-value> </init-param> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.filter.LoggingFilter</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-serlvet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
Drop me your questions and comments below.
Happy Learning !!
Reference :
ANIL KISHANRAO BHAWANGIRKAR
I am receiving below these exceptions all the time. Can you please help me what is these exeptions and how to fix it?
1. Exception recieved during upload : Unable to upload. Reason: java.io.IOException: Error writing request body to server.
2. Exception recieved during upload : Unable to upload. Reason: Error reading entity from input stream
PCD Pharma
Awesome explanation. Very Helpful.
Thank you.
RB
Hi,
This is very nicely explained. But can you please give an example how to implement a PATCH method.
I used the same technique explained here.
When I start my server it gives following error :-
SEVERE: A sub-resource locator, public javax.ws.rs.core.Response com.rest.service.web.MyService.patchEmployeeById(com.
rest.service.dto.EmployeeDto, java.lang.String), can not have an entity parameter. Try to move the parameter to the corresponding resource method.
SEVERE: Missing dependency for method public javax.ws.rs.core.Response com.rest.service.web.MyService.patchEmployeeById(com.
rest.service.dto.EmployeeDto, java.lang.String) at parameter at index 1
<The following errors and warnings have been detected with resource and/or provider clas
ses:
Ritesh Kumar
Hi,
Nice Article!
One clarification I need regarding Client.
How to generate stub here, like in case of SOAP we get wsdl but here we have only wadl which don’t give complete information.
So, can guide me like how to generate stub?
Cales
Hi,
unfortunately, I don’t understand what are the imports for the following code and my Eclipse give the message “The method newClient(Configuration) in the type ClientBuilder is not applicable for the arguments (ClientConfig)”. Can you help me please ? :
Mihai Nedelea
Hello,
I like very much how you explain.
Please, can you put complete source?
Best regards!
farhan
Your article is very good and helpful for me to learn rest services. Thanks.
shivam
where is download code ?
Anthony Clink
This is very well written and I am very impressed with the completeness while maintaining brevity. Thank you for the article. I however would have liked you to show why you wrapped the list object. Most new programmers would not understand serialization issues with that.
GS
Hi Lokesh,
I am getting this error. Can you help me to resolve this?
Apr 06, 2016 11:16:05 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Sending client request on thread main
1 > GET http://localhost:8080/JerseyDemos/rest/employees
1 > Accept: application/xml
Apr 06, 2016 11:16:05 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Client response received on thread main
1 < 404
1 < Content-Language: en
1 < Content-Length: 967
1 < Content-Type: text/html;charset=utf-8
1 < Date: Wed, 06 Apr 2016 16:16:05 GMT
1 < Server: Apache-Coyote/1.1
Exception in thread "main" org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/html;charset=utf-8, type=class com.howtodoinjava.jersey.Employees, genericType=class com.howtodoinjava.jersey.Employees.
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:232)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:853)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:785)
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:419)
at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108)
at com.howtodoinjava.jersey.Client.main(Client.java:27)
Lokesh Gupta
Set content-type request header to -> “application/xml”