Spring BootSpring Boot + Jersey REST + JPA + Hibernate CRUD 展示
本页将介绍Spring boot
Jersey REST
JPA
Hibernate
CRUD
的例子。Jersey
是JAX-RS
的实现。JAX-RS
是用于RESTful
Web
服务的Java API
。Jersey RESTful Web
服务是由SUN Microsystems
提供的开源。Jersey
是JSR 311
和其他附加功能的参考实现。在我们的演示应用程序中,我们将使用Jersey 2
来创建RESTful web
服务。我们将在这里讨论JAX-RS API
,它将被用来创建Jersey RESTful Web
服务和Jersey
客户端,然后我们将为Jersey RESTful Web
服务和Jersey
客户端创建演示应用程序。我们将使用JPA
和Hibernate
执行CRUD
操作。
1. 创建一个Jersey
端点,并用Spring
@Component
注解对其进行注解。
2. 使用带有@Component
注释的ResourceConfig
实现一个类,并使用register()
方法注册端点。
现在我们已经准备好使用我们的Jersey RESTful
网络服务了。为了处理CORS
,我们将创建一个过滤器。找到完整的Jersey RESTful
网络服务和Jersey
客户端应用程序的步骤。
演示工具版本
- Java 8
- Spring Boot 1.5.3.RELEASE
- Jersey 2.25.1
- Maven 3.3
- MySQL 5.5
- Eclipse Mars
Jersey REST Web 服务的 JAX-RS API
找到JAX-RS API
来创建Jersey REST
网络服务端点。
1. 找到javax.ws.rs
的API
来处理HTTP
方法。
@GET: 用@GET
注解的方法响应HTTP GET
方法。
@POST: 用@POST
注解的方法响应HTTP POST
方法。
@PUT: 用@PUT
注解的方法响应HTTP PUT
方法。
@DELETE: 用@DELETE
注解的方法响应HTTP DELETE
方法。
@HEAD: 用@HEAD
注解的方法会响应HTTP HEAD
方法。
@OPTIONS: 用@OPTIONS
注解的方法会响应HTTP OPTIONS
方法。
2.
找到javax.ws.rs
的API
来处理路径。
@Path
它定义了一个类或方法的URI
路径。它可以在方法和类的层面上用相对路径进行注释。
@Path("/article")
public class ArticleEndpoint {
@GET
@Path("/details")
public Response getArticleDetails() { }
}
@ApplicationPath
它定义了应用路径,作为@Path
提供的所有资源URI
的基础URI
。@ApplicationPath
在ResourceConfig
的子类中使用。
@ApplicationPath("/spring-app")
public class JerseyConfig extends ResourceConfig {
}
现在,访问我们的REST
网络服务示例getArticleDetails()
方法的URI
将如下所示。
/spring-app/article/details
3. 找到javax.ws.rs
的API
来生产和消费媒体类型。
@Produces
它定义了该方法所能产生的媒体类型。如果没有定义媒体类型,那么容器可以假设产生任何类型的媒体类型。方法级别的@Produces
所定义的媒体类型会覆盖类级别的@Produces
所定义的媒体类型。如果 HTTP
请求要求的媒体类型不能由REST Web
服务方法产生,那么容器必须以HTTP
状态 406
不可接受来响应。
@GET
@Path("/details")
@Produces(MediaType.APPLICATION_JSON)
public Response getArticleDetails() {
}
上述方法将产生媒体类型为application/json
。
@Consumes
它定义了该方法所能消费的媒体类型。如果没有定义媒体类型,那么容器可以假设消费任何类型的媒体类型。方法级别的@Consumes
所定义的媒体类型覆盖了类级别的@Consumes
所定义的媒体类型。如果HTTP
请求的媒体类型不能被REST Web
服务方法所消费,那么容器必须以HTTP
状态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. 找到javax.ws.rs
的API
来生产和消费媒体类型。
@PathParam:它将URI
模板参数的值与资源方法参数绑定。找到这个例子。
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getArticleById(@PathParam("id") Integer id) {
}
@QueryParam:它将HTTP
查询参数的值绑定到一个资源方法参数。找到这个例子。
@GET
@Path("/data")
@Produces(MediaType.APPLICATION_JSON)
public Response getArticleById(@QueryParam("id") Integer id) {
}
@CookieParam: 它将HTTP cookie
的值与一个资源方法参数绑定。
@FormParam: 它将请求实体中的表单参数值与资源方法参数绑定。
@HeaderParam: 它将HTTP
头与一个资源方法参数绑定。
@MatrixParam: 它将URI
Matrix
参数与资源方法参数绑定。
@DefaultValue: 它将默认值绑定到一个资源方法参数上。@DefaultValue
可与@PathParam
、@QueryParam
等一起使用。
@BeanParam: 它将自定义的JAX-RS
参数聚合器值对象注入到一个资源类字段中。
用于Jersey客户端的JAX-RS API
找到Jersey
客户端的JAX-RS API
。
1. Client
Client
是一个接口,包含在javax.ws.rs.client
包中。Client
在JAX-RS 2.0
中被引入。Jersey 2
使用Client
作为执行客户端请求的主要入口点,以消费从RESTful Web
服务返回的响应。Client
是一个重量级的对象。所以我们应该避免创建这么多的Client
实现对象。有必要通过调用close()
方法来关闭Client
对象,以避免资源泄漏。
Client client = ClientBuilder.newClient();
---
client.close();
2. WebTarget
WebTarget
是一个包含在javax.ws.rs.client
包中的接口。它在JAX-RS 2.0
中被引入。WebTarget
是一个由资源URI
识别的资源目标。
WebTarget base = client.target("http://localhost:8080/spring-app/article");
我们可以使用WebTarget
的path()
方法将URI
附加到基础URI
上。path()
方法返回WebTarget
的实例。
WebTarget details = base.path("details");
因此,最终的URL
将变成如下所示。
http://localhost:8080/spring-app/article/details
如果我们想添加查询参数,请按如下步骤操作。
WebTarget details = base.path("details").queryParam("id", "101");
如果我们想添加路径参数,请按如下步骤操作。
WebTarget articleById = base.path("{id}").resolveTemplate("id", "101");
3. SyncInvoker 和 Invocation.Builder
SyncInvoker
是用于同步调用HTTP
方法的统一接口。Invocation.Builder
是SyncInvoker
接口的实现类。
现在找到SyncInvoker
接口的方法,这些方法用于与REST
网络服务资源交互。
get(): 同步调用当前请求的HTTP GET
方法。
post(): 同步调用当前请求的HTTP POST
方法。
put(): 同步调用当前请求的HTTP PUT
方法。
delete(): 同步调用当前请求的HTTP DELETE
方法。
head(): 同步调用当前请求的HTTP HEAD
方法。
options(): 同步调用当前请求的HTTP OPTIONS
方法。
要获得Invocation.Builder
的实例,我们需要调用以下方法。
WebTarget.request(MediaType... acceptedResponseTypes)
例如
Invocation.Builder builder = details.request(MediaType.APPLICATION_JSON);
我们知道Invocation.Builder
是SyncInvoker
的实现,所以我们可以调用get()
方法,如下所示。
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
和MultivaluedHashMap
是javax.ws.rs.core
包的API
。
使用 Jersey 和 Spring Boot 的 REST 网络服务
我们现在将为Jersey RESTful
网络服务创建我们的演示应用程序。我们将对文章进行CRUD
操作。我们将提供Jersey
端点来创建、读取、更新和删除文章。
1. CRUD 的 REST Web服务URL
在我们的例子中,我们将创建以下REST
网络服务URL
,用于CRUD
操作。
1. Create :HTTP
方法: POST
, 网址: /spring-app/article/add
HTTP
响应状态代码: 201 CREATED
和409 CONFLICT
2. Read :HTTP
方法: GET
, 网址: /spring-app/article/{id}
HTTP
方法: GET
, 网址: /spring-app/article/details
HTTP
响应状态代码: 200 OK
3. Update :HTTP
方法: PUT
, 网址: /spring-app/article/update
HTTP
响应状态代码: 200 OK
4. Delete :HTTP
方法: DELETE
, 网址: /spring-app/article/{id}
HTTP
响应状态代码: 204 NO CONTENT
2. 项目结构
3. Maven 文件
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
启动器的描述。
spring-boot-starter-parent: 用于依赖关系管理的父POM
。
spring-boot-starter-web: 构建Web
、REST
应用程序的启动器。它使用Tomcat
服务器作为默认的嵌入式服务器。
spring-boot-starter-data-jpa: Spring data JPA
与hibernate
的启动程序。
spring-boot-starter-jersey: Jersey
RESTful
网络服务的启动器。
spring-boot-devtools: 它提供了开发者工具。这些工具在应用开发模式中很有帮助。开发者工具的一个特点是在代码发生任何变化时自动重新启动服务器。
spring-boot-maven-plugin: 它用于创建应用程序的可执行JAR
。
4. 创建 Jersey 端点
找到Jersey
端点,它将定义网络服务方法。我们将创建用于创建、读取、更新和删除操作的方法。
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.使用 ResourceConfig 注册 Jersey 端点
要注册Jersey
端点,我们需要创建一个实现ResourceConfig
的类,并调用其register()
方法,并将端点作为参数传递。
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()
方法。
public JerseyConfig() {
register(UserEndpoint.class);
register(ArticleEndpoint.class);
}
@ApplicationPath:它定义了应用路径,它被用作@Path
提供的所有资源URI
的基础URI
。应用路径的默认值是"/"
。
6. CORS配置
在Jersey RESTful web
服务中,为了处理跨源资源共享 (CORS
),我们将创建一个过滤器。我们需要保持它的顺序最高,这样它就可以为每个请求提供服务。
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() {
}
}
在上面的代码中,我们启用了以下URL
http://localhost:8585
运行在上述领域的应用程序可以使用脚本访问我们的Jersey RESTful
网络服务。
7. 使用 MySQL 创建数据库
找到用于 CRUD 操作的 MySQL 数据库架构。
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');
找到数据库表的JPA
实体。
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. 创建 application.properties
在Spring boot
中,为了配置数据库相关属性、Hibernate
和日志,我们需要使用application.properties
。我们使用的是Hibernate
实现的JPA
规范。
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.*
来配置数据源相关属性。使用前缀spring.jpa.properties.*
来配置JPA
相关属性。
我们可以在application.properties
中配置以下Jersey
属性来改变Jersey
的默认Spring boot
配置。
spring.jersey.application-path: 作为基础URI
的应用路径。它覆盖了@ApplicationPath
的值。
spring.jersey.type: 该值可以是servlet
或过滤器。默认值是servlet
。
spring.jersey.filter.order: 它定义了Jersey
过滤器链顺序。默认值为0
。
spring.jersey.init.*: 将被传递给Jersey servlet
或过滤器的初始参数。
spring.jersey.servlet.load-on-startup: Jersey servlet
启动时的加载优先级。默认为-1
。
9. 创建 DAO
找到 DAO 接口。
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);
}
找到DAO
接口的实现。我们在这里使用JPA EntityManager
来与数据库进行交互。
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. 创建 Service
找到服务接口和它的实现。
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. 使用 SpringApplication 创建主类
创建一个带有main()
方法的类,它将调用SpringApplication.run()
来运行该应用程序。我们需要用@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 客户端
这里我们将创建Jersey
客户端。我们将执行CRUD
操作。我们将创建用于创建、读取、更新和删除操作的方法。
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);
}
}
运行应用程序
要运行该应用程序,首先在MySQL
中创建表,如例子中给出的。现在我们可以通过以下方式运行REST
网络服务。
1. 使用Eclipse:使用页面末尾的下载链接下载项目的源代码。将该项目导入eclipse
。使用命令提示符,进入项目的根文件夹并运行。
mvn clean eclipse:eclipse
2. 使用Maven命令:下载项目的源代码。使用命令提示符进入项目的根文件夹,运行命令。
mvn spring-boot:run
然后在eclipse
中刷新项目。单击Run as
-> Java Application
运行主类 ApplicationStarter
。 Tomcat
服务器将启动。
3. 使用可执行的JAR:使用命令提示符,进入项目的根文件夹并运行命令。
mvn clean package
我们将在目标文件夹中得到可执行的JAR
包spring-boot-demo-0.0.1-SNAPSHOT.jar
。以下列方式运行这个JAR
java -jar target/spring-boot-demo-0.0.1-SNAPSHOT.jar
Tomcat
服务器将被启动。
现在我们已经准备好测试这个应用程序了。要运行客户端,在eclipse
中进入JerseyClient
类,点击Run as
-> Java Application
。
我们也可以用Postman
测试应用程序。
参考文献
【1】JAX-RS and Jersey
【2】Package javax.ws.rs
【3】Advanced Features of the Client API
【4】Spring Boot REST JPA Hibernate MySQL Example
【5】Spring Boot Jersey REST JPA Hibernate CRUD Example
源码下载
提取码:mao4
spring-boot-jersey-rest-jpa-hibernate-crud-example.zip
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgkijcj
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13