In this article, we will learn step by step how to develop CRUD RESTFul APIs using the Jersey JAX-RS framework.
In this article, we have used the Jersey version 2.27 with JDK 8. Deployment of a JAX-RS application using @ApplicationPath with Servlet 3.0 ( use @ApplicationPath("resources")annotation to configure Jersey Servlet Container).
guide to creating a maven web project in eclipse.
In this article, we have used the Jersey version 2.27 with JDK 8. Deployment of a JAX-RS application using @ApplicationPath with Servlet 3.0 ( use @ApplicationPath("resources")annotation to configure Jersey Servlet Container).
- Maven 3
- JDK 8
- Jersey 2.27
- Apache Tomcat 8.5
- Eclipse Neon
1. Create a Maven Web Application Project
You can create a quick start Java web application project by using the Maven
maven-archetype-webapp
template. In a terminal (*Unix or Mac) or command prompt (Windows), navigate to the folder you want to create the project.
Type this command :
$ mvn archetype:generate -DgroupId={project-packaging}
-DartifactId={project-name}
-DarchetypeArtifactId=maven-archetype-webapp
-DinteractiveMode=false
//for example
$ mvn archetype:generate -DgroupId=com.ramesh
-DartifactId=Jersey-crud-example
-DarchetypeArtifactId=maven-archetype-webapp
-DinteractiveMode=false
Or You can use Guide to Create a Simple Maven Web Applicationguide to creating a maven web project in eclipse.
2. Project Packaging Structure
In a typical Jersey application, the project packaging structure may look:
── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── javadevelopersguide
│ │ └── jersey
│ │ ├── model
│ │ │ └── User.java
│ │ ├── service
│ │ │ ├── UserService.java
│ │ │ └── impl
│ │ │ └── UserServiceImpl.java
│ │ └── resources
│ │ | └── UserResource.java
│ │ └── client
│ │ └── UserResourceClient.java
│ ├── resources
└── logback.xml
│ └── webapp
│ ├── WEB-INF
│ │ ├── classes
│ │ └── web.xml
│ ├── images
│ └── styles
└── test
├── java
│ └── com
│ └── javadevelopersguide
│ └── jersey
│ └── resources
│ └── UserResourceTest.java
└── resources
└── logback-test.xml
3. Update Jersey Dependencies in a Pom.Xml File
<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.javadevelopersguide.jersey</groupId>
<artifactId>jersey-crud-example</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>jersey-crud-example Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-moxy -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- Required only when you are using JAX-RS Client -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
</dependencies>
<build>
<finalName>jersey-crud-example</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
<properties>
<jersey.version>2.26</jersey.version>
</properties>
</project>
4. Data Model - User
Let's create a User class, which is a data model for this RESTful CRUD services.
I have used jersey-moxy- json support for JSON binding feature from
jersey-media-moxy
.package com.javadevelopersguide.jersey.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
private long id;
private String name;
private String email;
public User() {
}
public User(long id, String name, String email) {
super();
this.id = id;
this.name = name;
this.email = email;
}
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
5. Create a Resource class - UserResource.java
Let's create a resource class named UserResource class with following RESTFul APIs:
- Create User
- Get All User
- Update User
- Delete User
- Get User By Id
- Create User
- Get All User
- Update User
- Delete User
- Get User By Id
package com.javadevelopersguide.jersey.resources;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.javadevelopersguide.jersey.model.User;
import com.javadevelopersguide.jersey.services.UserService;
@Path("/users")
public class UserResource {
private UserService userService = new UserService();
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<User> fetchAll() {
return userService.fetchAll();
}
@GET
@Path("user/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response get(@PathParam("id") int id) {
return Response.ok().entity(new User(100, "me", "me@gmail.com")).build();
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response create(User user) {
// create notification
userService.create(user);
return Response.status(Status.CREATED).build();
}
@PUT
@Path("/user/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response update(@PathParam("id") long id, User user) {
userService.update(user);
return Response.noContent().build();
}
@DELETE
@Path("/user/{id}")
public Response delete(@PathParam("id") long id) {
userService.delete(id);
return Response.status(202).entity("User deleted successfully !!").build();
}
}
6. Descriptor-Less Deployment Configuration
Here are multiple deployment options in the Servlet 3.0 container for a JAX-RS application defined by implementing a custom Application subclass. For simple deployments, no web.xml is necessary at all.
Instead, an @ApplicationPath annotation can be used to annotate the custom Application subclass and define the base application URI for all JAX-RS resources configured in the application:
Instead, an @ApplicationPath annotation can be used to annotate the custom Application subclass and define the base application URI for all JAX-RS resources configured in the application:
import javax.ws.rs.ApplicationPath;
// Deployment of a JAX-RS application using @ApplicationPath with Servlet 3.0
// Descriptor-less deployment
import org.glassfish.jersey.server.ResourceConfig;
@ApplicationPath("/api")
public class JerseyServletContainerConfig extends ResourceConfig {
public JerseyServletContainerConfig() {
packages("com.javadevelopersguide.jersey.resources");
}
}
7. Create Sample UserService class
Let's create a UserService class to serve in-memory objects to UserResource class.
package com.javadevelopersguide.jersey.services;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.NotFoundException;
import com.javadevelopersguide.jersey.model.User;
public class UserService {
private List<User> users = new ArrayList<User>();
public List<User> fetchAll() {
users.add(new User(100, "A", "demo@gmail.com"));
users.add(new User(101, "B", "demo1@gmail.com"));
users.add(new User(102, "C", "demo2@gmail.com"));
return users;
}
public User fetchBy(long id) throws NotFoundException {
for (User user2 : fetchAll()) {
if (id == user2.getId()) {
return user2;
}else{
throw new NotFoundException("Resource not found with Id :: " + id);
}
}
return null;
}
public void create(User user) {
users.add(user);
}
public void update(User user) {
for (User user2 : users) {
if (user.getId() == user2.getId()) {
users.remove(user2);
users.add(user);
}
}
}
public void delete(long id) throws NotFoundException {
// TODO: delete operation
}
}
8. Jersey JAX-RS Client for Rest API
Jersey Test Framework originated as an internal tool used for verifying the correct implementation of server-side components.
If you want to develop a test using Jersey Test Framework, you need to subclass JerseyTest and configure the set of resources and/or providers that will be deployed as part of the test application.
The below short code snippet shows basic resource class UserResource used in tests defined as part of the UserResourceTest class. The overridden configure method returns a ResourceConfig of the test application, that contains only the UserResource resource class. ResourceConfig is a sub-class of JAX-RS Application. It is a Jersey convenience class for configuring JAX-RS applications. ResourceConfig also implements JAX-RS Configurable interface to make the application configuration more flexible.
package com.javadevelopersguide.jersey.client;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.javadevelopersguide.jersey.model.User;
public class UserResourceClient {
public static void main(String[] args) {
//getUsers();
getUser();
// createUser();
// updateUser();
//deleteUser();
}
private static void getUsers() {
Client client = ClientBuilder.newClient();
String entity = client.target("http://localhost:8080/jersey-crud-example/api").path("users")
.request(MediaType.APPLICATION_JSON).header("some-header", "true").get(String.class);
System.out.println(entity);
}
private static void getUser() {
Client client = ClientBuilder.newClient();
String entity = client.target("http://localhost:8080/jersey-crud-example/api").path("users").path("user/100")
.request(MediaType.APPLICATION_JSON).header("some-header", "true").get(String.class);
System.out.println(entity);
}
private static void createUser() {
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target("http://localhost:8080/jersey-crud-example/api").path("users");
User user = new User();
user.setId(1);
user.setName("Ramesh");
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
Response response = invocationBuilder.post(Entity.entity(user, MediaType.APPLICATION_JSON));
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));
}
private static void updateUser() {
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target("http://localhost:8080/jersey-crud-example/api").path("users")
.path("user/1");
User user = new User();
user.setId(1);
user.setName("Ramesh");
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
Response response = invocationBuilder.put(Entity.entity(user, MediaType.APPLICATION_JSON));
String userJson = response.readEntity(String.class);
System.out.println(response.getStatus());
System.out.println(userJson);
}
private static void deleteUser() {
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target("http://localhost:8080/jersey-crud-example/api").path("users")
.path("user/100");
User user = new User();
user.setId(1);
user.setName("Ramesh");
Invocation.Builder invocationBuilder = webTarget.request();
Response response = invocationBuilder.delete();
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));
}
}
9. Deployment
Development is completed, it's time to deploy this web application, so either it can be deployed from an external Tomcat server or run from eclipse.
Rest endpoint URLs, request and response details for your reference.
Rest endpoint URLs, request and response details for your reference.
To fetch all the users.
Http Method : GET
http://localhost:8080/jersey-spring-integration/users
Response JSON :
[{"email":"demo@gmail.com","id":100,"name":"A"},{"email":"demo1@gmail.com","id":101,"name":"B"},{"email":"demo2@gmail.com","id":102,"name":"C"}]
Get specific user by id
Http Method : GET
http://localhost:8080/jersey-spring-integration/users/user/100
Response : {"email":"me@gmail.com","id":100,"name":"me"}
Create a new user
Http Method : POST
http://localhost:8080/jersey-spring-integration/users
Request JSON : {"email":"demod@gmail.com","id":106,"name":"D"}
Response : 201
Update a user
Http Method : PUT
http://localhost:8080/jersey-spring-integration/users/user/100
Request JSON : {"email":"demod@gmail.com","id":100,"name":"D"}
Response : 200
Delete a user
Http Method : DELETE
http://localhost:8080/jersey-spring-integration/users/user/100
Response : 204
10. Conclusion
This article illustrated how to implement a Jersey JAX-RS Restful CRUD Web Services Example using latest jersey rest 2.27, jersey client and ResourceConfig @ApplicationPath annotation based configuration.In the next article of the series, we will focus on more Jersey rest examples, concepts, and more.
All the code of this article is available over on Github. This is a Maven-based project, so it should be easy to import and run as it is.
Github Repository: Jersey JAX-RS Restful CRUD Web Services Example
Comments
Post a Comment
Leave Comment