Spring Boot + Jersey REST + JPA + Hibernate CRUD Example
June 11, 2017
This page will walk through Spring boot + Jersey REST + JPA + Hibernate CRUD example. Jersey is the JAX-RS implementation. JAX-RS is the Java API for RESTful web services. Jersey RESTful web service is the open source provided by SUN Microsystems. Jersey is the reference implementation for JSR 311 and other additional features. In our demo application we will use Jersey 2 to create RESTful web service. We will discuss here JAX-RS API that will be used to create Jersey RESTful web service and Jersey client and then we will create demo application for Jersey RESTful web service and Jersey client both. We will perform CRUD operation using JPA and Hibernate.
To integrate Spring boot with Jersey, we need to follow given points.
1. Create a Jersey endpoint and annotate it with Spring
@Component
annotation.
2. Implement a class using
ResourceConfig
annotated with @Component
and register endpoints using register()
method.
Now we are ready to work with our Jersey RESTful web service. To handles CORS we will create a Filter. Find the complete Jersey RESTful web service and Jersey client application step by step.
Contents
- Technologies Used
- JAX-RS API for Jersey REST Web Service
- JAX-RS API for Jersey Client
- REST Web Service using Jersey and Spring Boot
- 1. REST Web Service URLs for CRUD
- 2. Project Structure using Eclipse
- 3. Create Maven File
- 4. Create Jersey Endpoint
- 5. Register Jersey Endpoints using ResourceConfig
- 6. CORS Configuration
- 7. Create Database using MySQL
- 8. Create application.properties
- 9. Create DAO
- 10. Create Service
- 11. Create Main using SpringApplication
- Jersey Client
- Run Application
- References
- Download Source Code
Technologies Used
Find the technologies being used in our application.1. Java 8
2. Spring Boot 1.5.3.RELEASE
3. Jersey 2.25.1
4. Maven 3.3
5. MySQL 5.5
6. Eclipse Mars
JAX-RS API for Jersey REST Web Service
Find the JAX-RS API to create Jersey REST web service endpoints.1. Find the
javax.ws.rs
API to handle HTTP methods.
@GET: The method annotated with
@GET
responds to HTTP GET method.
@POST: The method annotated with
@POST
responds to HTTP POST method.
@PUT: The method annotated with
@PUT
responds to HTTP PUT method.
@DELETE: The method annotated with
@DELETE
responds to HTTP DELETE method.
@HEAD: The method annotated with
@HEAD
responds to HTTP HEAD method.
@OPTIONS
: The method annotated with @OPTIONS
responds to HTTP OPTIONS method.
2. Find the
javax.ws.rs
API to handle paths.
@Path
It defines a URI path for a class or method. It can be annotated on methods and class level with a relative path.
@Path("/article") public class ArticleEndpoint { @GET @Path("/details") public Response getArticleDetails() { } }
It defines the application path that is used as base URI for all resource URIs provides by
@Path
. @ApplicationPath
is used at subclass of ResourceConfig
.
@ApplicationPath("/spring-app") public class JerseyConfig extends ResourceConfig { }
getArticleDetails()
REST web service method will be as given below.
/spring-app/article/details
javax.ws.rs
API to produce and consume media type.
@Produces
It defines the media types that the method can produce. If no media type is defined then container can assume to produce any type of media type. The media type defined by
@Produces
at method level overrides the media type defined by @Produces
at class level. If a HTTP request demands a media type that cannot be produced by REST web service method then the container must respond with HTTP status 406 Not Acceptable.
@GET @Path("/details") @Produces(MediaType.APPLICATION_JSON) public Response getArticleDetails() { }
application/json
.
@Consumes
It defines the media types that the method can consume. If no media type is defined then container can assume to consume any type of media type. The media type defined by
@Consumes
at method level overrides the media type defined by @Consumes
at class level. If a HTTP request has a media type that cannot be consumed by REST web service method then the container must respond with HTTP status 415 Unsupported Media Type.
@DELETE @Path("/{id}") @Consumes(MediaType.APPLICATION_JSON) public Response deleteArticle(@PathParam("id") Integer id) { articleService.deleteArticle(id); return Response.noContent().build(); }
application/json
.
4. Find the
javax.ws.rs
API to produce and consume media type.
@PathParam: It binds the value of URI template parameter to a resource method parameter. Find the example.
@GET @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) public Response getArticleById(@PathParam("id") Integer id) { }
@GET @Path("/data") @Produces(MediaType.APPLICATION_JSON) public Response getArticleById(@QueryParam("id") Integer id) { }
@FormParam: It binds the value of form parameter in a request entity to a resource method parameter.
@HeaderParam: It binds the HTTP header to a resource method parameter.
@MatrixParam: It binds the URI matrix parameter to a resource method parameter.
@DefaultValue: It binds the default value to a resource method parameter.
@DefaultValue
is used with @PathParam
, @QueryParam
etc.
@BeanParam: It injects custom JAX-RS parameter aggregator value object into a resource class field.
JAX-RS API for Jersey Client
Find the JAX-RS API for Jersey client.1. Client
Client
is an interface which is contained in javax.ws.rs.client
package. Client
has been introduced in JAX-RS 2.0 . Jersey 2 uses Client
as the main entry point to execute client requests to consume responses returned from the RESTful web services. Client
is a heavy-weight object. So we should avoid creating so many objects of Client
implementations. It is necessary to close Client
object by calling close()
method to avoid leaking resources.
Client client = ClientBuilder.newClient(); --- client.close();
WebTarget
is an interface contained in javax.ws.rs.client
package. It has been introduced in JAX-RS 2.0 . WebTarget
is a resource target identified by resource URI.
WebTarget base = client.target("http://localhost:8080/spring-app/article");
path()
method of WebTarget
. path()
method returns the instance of WebTarget
.
WebTarget details = base.path("details");
http://localhost:8080/spring-app/article/details
WebTarget details = base.path("details").queryParam("id", "101");
WebTarget articleById = base.path("{id}").resolveTemplate("id", "101");
SyncInvoker
is the uniform interface for synchronous invocation of HTTP methods. Invocation.Builder
is the implementation class of SyncInvoker
interface.
Now find the methods of
SyncInvoker
interface that are used to interact with REST web service resources.
get(): Invoke HTTP GET method for current request synchronously.
post(): Invoke HTTP POST method for current request synchronously.
put(): Invoke HTTP PUT method for current request synchronously.
delete(): Invoke HTTP DELETE method for current request synchronously.
head(): Invoke HTTP HEAD method for current request synchronously.
options(): Invoke HTTP OPTIONS method for current request synchronously.
To get instance of
Invocation.Builder
we need to call following method.
WebTarget.request(MediaType... acceptedResponseTypes)
Invocation.Builder builder = details.request(MediaType.APPLICATION_JSON);
Invocation.Builder
is the implementation of SyncInvoker
, so we can call get()
method as follows.
public void getArticleDetails() { Client client = ClientBuilder.newClient(); WebTarget base = client.target("http://localhost:8080/spring-app/article"); WebTarget details = base.path("details"); List<Article> list = details.request(MediaType.APPLICATION_JSON) .get(new GenericType<List<Article>>() {}); list.stream().forEach(article -> System.out.println(article.getArticleId()+", "+ article.getTitle()+", "+ article.getCategory())); client.close(); }
MultivaluedMap<String, Object> myHeaders = new MultivaluedHashMap<>(); myHeaders.add("Content-Type", "application/json"); List<Article> list = details.request(MediaType.APPLICATION_JSON).headers(myHeaders) .get(new GenericType<List<Article>>() {});
MultivaluedMap
and MultivaluedHashMap
is the API of javax.ws.rs.core
package.
REST Web Service using Jersey and Spring Boot
We will create our demo application now for Jersey RESTful web service. We will perform CRUD operation on articles. We will provide Jersey endpoint to create, read, update and delete article.1. REST Web Service URLs for CRUD
In our example we will create following REST web service URLs for CRUD operation.1. Create :
HTTP Method: POST, URL: /spring-app/article/add
HTTP Response Status Code: 201 CREATED and 409 CONFLICT
2. Read :
HTTP Method: GET, URL: /spring-app/article/{id}
HTTP Method: GET, URL: /spring-app/article/details
HTTP Response Status Code: 200 OK
3. Update :
HTTP Method: PUT, URL: /spring-app/article/update
HTTP Response Status Code: 200 OK
4. Delete :
HTTP Method: DELETE, URL: /spring-app/article/{id}
HTTP Response Status Code: 204 NO CONTENT
2. Project Structure using Eclipse
Find the structure of our demo project in eclipse.
3. Create Maven File
Find the Maven file used in our example.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.concretepage</groupId> <artifactId>spring-boot-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-demo</name> <description>Spring Boot Demo Project</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jersey</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
spring-boot-starter-parent: Parent POM for dependency management.
spring-boot-starter-web: Starter for building web, REST applications. It uses tomcat server as default embedded server.
spring-boot-starter-data-jpa: Starter for Spring data JPA with hibernate.
spring-boot-starter-jersey: Starter for Jersey RESTful web service.
spring-boot-devtools: It provides developer tools. These tools are helpful in application development mode. One of the features of developer tool is automatic restart of the server for any change in code.
spring-boot-maven-plugin: It is used to create executable JAR of the application.
4. Create Jersey Endpoint
Find the Jersey endpoint that will define web service methods. We will create methods for create, read, update and delete operations.ArticleEndpoint.java
package com.concretepage.endpoint; import java.net.URI; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.concretepage.entity.Article; import com.concretepage.service.IArticleService; @Component @Path("/article") public class ArticleEndpoint { private static final Logger logger = LoggerFactory.getLogger(ArticleEndpoint.class); @Autowired private IArticleService articleService; @GET @Path("/details") @Produces(MediaType.APPLICATION_JSON) public Response getArticleDetails() { List<Article> list = articleService.getAllArticles(); return Response.ok(list).build(); } @GET @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) public Response getArticleById(@PathParam("id") Integer id) { Article article = articleService.getArticleById(id); return Response.ok(article).build(); } @POST @Path("/add") @Consumes(MediaType.APPLICATION_JSON) public Response addArticle(Article article) { boolean isAdded = articleService.addArticle(article); if (!isAdded) { logger.info("Article already exits."); return Response.status(Status.CONFLICT).build(); } return Response.created(URI.create("/spring-app/article/"+ article.getArticleId())).build(); } @PUT @Path("/update") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Response updateArticle(Article article) { articleService.updateArticle(article); return Response.ok(article).build(); } @DELETE @Path("/{id}") @Consumes(MediaType.APPLICATION_JSON) public Response deleteArticle(@PathParam("id") Integer id) { articleService.deleteArticle(id); return Response.noContent().build(); } }
5. Register Jersey Endpoints using ResourceConfig
To register Jersey endpoints, we need to create a class implementingResourceConfig
and call its register()
method and pass our endpoint as an argument.
JerseyConfig.java
package com.concretepage.config; import javax.ws.rs.ApplicationPath; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.stereotype.Component; import com.concretepage.endpoint.ArticleEndpoint; @Component @ApplicationPath("/spring-app") public class JerseyConfig extends ResourceConfig { public JerseyConfig() { register(ArticleEndpoint.class); } }
register()
method more than one time.
public JerseyConfig() { register(UserEndpoint.class); register(ArticleEndpoint.class); }
@Path
. Default value for application path is "/"
6. CORS Configuration
In Jersey RESTful web service, to handle Cross-Origin-Resource-Sharing (CORS), we will create a Filter. We need to keep its order highest, so that it can be served for every request.CORSFilter.java
package com.concretepage.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component @Order(Ordered.HIGHEST_PRECEDENCE) public class CORSFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setHeader("Access-Control-Allow-Origin", "http://localhost:8585"); httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); httpResponse.setHeader("Access-Control-Allow-Headers", "X-Auth-Token, Content-Type"); httpResponse.setHeader("Access-Control-Expose-Headers", "custom-header1, custom-header2"); httpResponse.setHeader("Access-Control-Allow-Credentials", "false"); httpResponse.setHeader("Access-Control-Max-Age", "4800"); chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
http://localhost:8585
7. Create Database using MySQL
Find the MySQL database schema for CRUD operation.Database Schema
-- Dumping database structure for concretepage CREATE DATABASE IF NOT EXISTS `concretepage` ; USE `concretepage`; -- Dumping structure for table concretepage.articles CREATE TABLE IF NOT EXISTS `articles` ( `article_id` int(5) NOT NULL AUTO_INCREMENT, `title` varchar(200) NOT NULL, `category` varchar(100) NOT NULL, PRIMARY KEY (`article_id`) ) ENGINE=InnoDB AUTO_INCREMENT=105 DEFAULT CHARSET=latin1; -- Dumping data for table concretepage.articles: ~4 rows (approximately) INSERT INTO `articles` (`article_id`, `title`, `category`) VALUES (101, 'Angular 2 Tutorial using CLI', 'Angular'), (102, 'Spring Boot Getting Started', 'Spring Boot'), (103, 'Lambda Expressions Java 8 Example', 'Java 8'), (104, 'Android AsyncTask Example', 'Android');
Article.java
package com.concretepage.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="articles") public class Article implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="article_id") private int articleId; @Column(name="title") private String title; @Column(name="category") private String category; public int getArticleId() { return articleId; } public void setArticleId(int articleId) { this.articleId = articleId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
8. Create application.properties
In Spring boot, to configure database related properties, Hibernate and logging, we need to useapplication.properties
. We are using Hibernate implementation of JPA specification.
application.properties
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/concretepage spring.datasource.username=root spring.datasource.password= spring.datasource.tomcat.max-wait=20000 spring.datasource.tomcat.max-active=50 spring.datasource.tomcat.max-idle=20 spring.datasource.tomcat.min-idle=15 spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect spring.jpa.properties.hibernate.id.new_generator_mappings = false spring.jpa.properties.hibernate.format_sql = true logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=INFO logging.level.com.concretepage= INFO
spring.datasource.*
to configure datasource related properties. Use prefix spring.jpa.properties.*
to configure JPA related properties.
We can configure following Jersey properties in
application.properties
to change default Spring boot configurations for Jersey.
spring.jersey.application-path: Application path that acts as base URI. It overrides the value of
@ApplicationPath
.
spring.jersey.type: The value can be servlet or filter. Default value is servlet.
spring.jersey.filter.order: It defines the Jersey filter chain order. Default value is 0.
spring.jersey.init.*: Init parameters that will be passed to Jersey servlet or filter.
spring.jersey.servlet.load-on-startup: Load on startup priority of Jersey servlet. Default is -1.
9. Create DAO
Find the DAO interface.IArticleDAO.java
package com.concretepage.dao; import java.util.List; import com.concretepage.entity.Article; public interface IArticleDAO { List<Article> getAllArticles(); Article getArticleById(int articleId); void addArticle(Article article); void updateArticle(Article article); void deleteArticle(int articleId); boolean articleExists(String title, String category); }
EntityManager
to interact with database.
ArticleDAO.java
package com.concretepage.dao; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.concretepage.entity.Article; @Transactional @Repository public class ArticleDAO implements IArticleDAO { @PersistenceContext private EntityManager entityManager; @Override public Article getArticleById(int articleId) { return entityManager.find(Article.class, articleId); } @SuppressWarnings("unchecked") @Override public List<Article> getAllArticles() { String hql = "FROM Article as atcl ORDER BY atcl.articleId"; return (List<Article>) entityManager.createQuery(hql).getResultList(); } @Override public void addArticle(Article article) { entityManager.persist(article); } @Override public void updateArticle(Article article) { Article artcl = getArticleById(article.getArticleId()); artcl.setTitle(article.getTitle()); artcl.setCategory(article.getCategory()); entityManager.flush(); } @Override public void deleteArticle(int articleId) { entityManager.remove(getArticleById(articleId)); } @Override public boolean articleExists(String title, String category) { String hql = "FROM Article as atcl WHERE atcl.title = ? and atcl.category = ?"; int count = entityManager.createQuery(hql).setParameter(1, title) .setParameter(2, category).getResultList().size(); return count > 0 ? true : false; } }
10. Create Service
Find the service interface and its implementation.IArticleService.java
package com.concretepage.service; import java.util.List; import com.concretepage.entity.Article; public interface IArticleService { List<Article> getAllArticles(); Article getArticleById(int articleId); boolean addArticle(Article article); void updateArticle(Article article); void deleteArticle(int articleId); }
package com.concretepage.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.concretepage.dao.IArticleDAO; import com.concretepage.entity.Article; @Service public class ArticleService implements IArticleService { @Autowired private IArticleDAO articleDAO; @Override public Article getArticleById(int articleId) { Article obj = articleDAO.getArticleById(articleId); return obj; } @Override public List<Article> getAllArticles(){ return articleDAO.getAllArticles(); } @Override public synchronized boolean addArticle(Article article){ if (articleDAO.articleExists(article.getTitle(), article.getCategory())) { return false; } else { articleDAO.addArticle(article); return true; } } @Override public void updateArticle(Article article) { articleDAO.updateArticle(article); } @Override public void deleteArticle(int articleId) { articleDAO.deleteArticle(articleId); } }
11. Create Main using SpringApplication
Create a class withmain()
method that will call SpringApplication.run()
to run the application. We need to annotate it with @SpringBootApplication
.
ApplicationStarter.java
package com.concretepage; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApplicationStarter { public static void main(String[] args) { SpringApplication.run(ApplicationStarter.class, args); } }
Jersey Client
Here we will create Jersey client. We will perform CRUD operation. We will create methods for create, read, update and delete operation.JerseyClient.java
package com.concretepage.client; import java.util.List; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import com.concretepage.entity.Article; public class JerseyClient { public void getArticleDetails() { Client client = ClientBuilder.newClient(); WebTarget base = client.target("http://localhost:8080/spring-app/article"); WebTarget details = base.path("details"); List<Article> list = details.request(MediaType.APPLICATION_JSON) .get(new GenericType<List<Article>>() {}); list.stream().forEach(article -> System.out.println(article.getArticleId()+", "+ article.getTitle()+", "+ article.getCategory())); client.close(); } public void getArticleById(int articleId) { Client client = ClientBuilder.newClient(); WebTarget base = client.target("http://localhost:8080/spring-app/article"); WebTarget articleById = base.path("{id}").resolveTemplate("id", articleId); Article article = articleById.request(MediaType.APPLICATION_JSON) .get(Article.class); System.out.println(article.getArticleId()+", "+ article.getTitle()+", "+ article.getCategory()); client.close(); } public void addArticle(Article article) { Client client = ClientBuilder.newClient(); WebTarget base = client.target("http://localhost:8080/spring-app/article"); WebTarget add = base.path("add"); Response response = add.request(MediaType.APPLICATION_JSON) .post(Entity.json(article)); System.out.println("Response Http Status: "+ response.getStatus()); System.out.println(response.getLocation()); client.close(); } public void updateArticle(Article article) { Client client = ClientBuilder.newClient(); WebTarget base = client.target("http://localhost:8080/spring-app/article"); WebTarget update = base.path("update"); Response response = update.request(MediaType.APPLICATION_JSON) .put(Entity.json(article)); System.out.println("Response Http Status: "+ response.getStatus()); Article resArticle = response.readEntity(Article.class); System.out.println(resArticle.getArticleId()+", "+ resArticle.getTitle()+", "+ resArticle.getCategory()); client.close(); } public void deleteArticle(int articleId) { Client client = ClientBuilder.newClient(); WebTarget base = client.target("http://localhost:8080/spring-app/article"); WebTarget deleteById = base.path("{id}").resolveTemplate("id", articleId); Response response = deleteById.request(MediaType.APPLICATION_JSON) .delete(); System.out.println("Response Http Status: "+ response.getStatus()); if(response.getStatus() == 204) { System.out.println("Data deleted successfully."); } client.close(); } public static void main(String[] args) { JerseyClient jerseyClient = new JerseyClient(); jerseyClient.getArticleDetails(); //jerseyClient.getArticleById(102); Article article = new Article(); article.setTitle("Spring REST Security using Hibernate2"); article.setCategory("Spring"); //jerseyClient.addArticle(article); article.setArticleId(105); //jerseyClient.updateArticle(article); //jerseyClient.deleteArticle(105); } }
Run Application
To run the application, first create table in MySQL as given in the example. Now we can run REST web service in following ways.1. Using Eclipse: Download the project source code using the download link given at the end of page. Import the project into eclipse. Using command prompt, go to the root folder of the project and run.
mvn clean eclipse:eclipse
ApplicationStarter
by clicking Run as -> Java Application. Tomcat server will be started.
2. Using Maven Command: Download the project source code. Go to the root folder of the project using command prompt and run the command.
mvn spring-boot:run
3. Using Executable JAR: Using command prompt, go to the root folder of the project and run the command.
mvn clean package
java -jar target/spring-boot-demo-0.0.1-SNAPSHOT.jar
Now we are ready to test the application. To run client, go to the
JerseyClient
class in eclipse and click on Run as -> Java Application.
We can also test application using Postman. Find the print screen.

I am done now. Happy Spring Boot and Jersey learning!
References
JAX-RS and JerseyPackage javax.ws.rs
Advanced Features of the Client API
Spring Boot REST + JPA + Hibernate + MySQL Example