Spring Boot + Jersey REST + JPA + Hibernate CRUD Example

By Arvind Rai, 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.

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() { }
}
@ApplicationPath
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 {
}
Now the URI to access our sample getArticleDetails() REST web service method will be as given below.
/spring-app/article/details 
3. Find the 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() {
} 
The above method will produce media type as 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();
} 
The above method will consume media type as 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) {
} 
@QueryParam: It binds the value of HTTP query parameter to a resource method parameter. Find the example.
@GET
@Path("/data")
@Produces(MediaType.APPLICATION_JSON)
public Response getArticleById(@QueryParam("id") Integer id) {
} 
@CookieParam: It binds the value of HTTP cookie to a resource method parameter.
@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(); 
2. WebTarget
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"); 
We can append the URI to base URI using path() method of WebTarget. path() method returns the instance of WebTarget.
WebTarget details = base.path("details"); 
So the final URL will become as follows.
http://localhost:8080/spring-app/article/details 
If we want to add query parameter, do as follows.
WebTarget details = base.path("details").queryParam("id", "101"); 
If we want to add path parameter, do as follows.
WebTarget articleById = base.path("{id}").resolveTemplate("id", "101"); 
3. SyncInvoker and Invocation.Builder
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) 
For Example
Invocation.Builder builder = details.request(MediaType.APPLICATION_JSON); 
As we know that 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();
} 
If we want to add request headers, do as follows.
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.
Spring Boot + Jersey REST + JPA + Hibernate CRUD Example

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> 
Find the description of Spring boot starter.
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 implementing ResourceConfig 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);
   }
} 
If we have more than one endpoints, we need to call register() method more than one time.
public JerseyConfig() {
   register(UserEndpoint.class);
   register(ArticleEndpoint.class);
} 
@ApplicationPath: It defines the application path that is used as base URI for all resource URIs provides by @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() {
	}
}  
In the above code we have enabled following URL
http://localhost:8585 
Application running on the above domain can access our Jersey RESTful web service using script.

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'); 
Find the JPA entity for the database table.
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 use application.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  
Use prefix 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);
} 
Find the implementation of DAO interface. We are using here JPA 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);
} 
ArticleService.java
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 with main() 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 
and then refresh the project in eclipse. Run Main class 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 
Tomcat server will be started.

3. Using Executable JAR: Using command prompt, go to the root folder of the project and run the command.
mvn clean package 
We will get executable JAR spring-boot-demo-0.0.1-SNAPSHOT.jar in target folder. Run this JAR as
java -jar target/spring-boot-demo-0.0.1-SNAPSHOT.jar 
Tomcat server will be started.

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.
Spring Boot + Jersey REST + JPA + Hibernate CRUD Example


I am done now. Happy Spring Boot and Jersey learning!

References

JAX-RS and Jersey
Package javax.ws.rs
Advanced Features of the Client API
Spring Boot REST + JPA + Hibernate + MySQL Example

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI









©2023 concretepage.com | Privacy Policy | Contact Us