- >() {});
list.stream().forEach(article ->
System.out.println(article.getArticleId()+", "+ article.getTitle()+", "+ article.getCategory()));
client.close();
}
- 演示工具版本
- Jersey REST Web 服务的 JAX-RS API
- 用于Jersey客户端的JAX-RS API
- 1. Client
- 2. WebTarget
- 3. SyncInvoker 和 Invocation.Builder
- 使用 Jersey 和 Spring Boot 的 REST 网络服务
- 1. CRUD 的 REST Web服务URL
- 2. 项目结构
- 3. Maven 文件
- 4. 创建 Jersey 端点
- 5.使用 ResourceConfig 注册 Jersey 端点
- 6. CORS配置
- 7. 使用 MySQL 创建数据库
- 8. 创建 application.properties
- 9. 创建 DAO
- 10. 创建 Service
- 11. 使用 SpringApplication 创建主类
- Jersey 客户端
- 运行应用程序
- 参考文献
- 源码下载
本页将介绍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
找到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. ClientClient是一个接口,包含在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 list = details.request(MediaType.APPLICATION_JSON)
.get(new GenericType
如果我们想添加请求头信息,请按以下方法操作。
MultivaluedMapmyHeaders = new MultivaluedHashMap<>(); myHeaders.add("Content-Type", "application/json"); List list = details.request(MediaType.APPLICATION_JSON).headers(myHeaders) .get(new GenericType >() {});
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
pom.xml
4.0.0 com.concretepage spring-boot-demo 0.0.1-SNAPSHOT jar spring-demo Spring Boot Demo Project org.springframework.boot spring-boot-starter-parent 1.5.3.RELEASE 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jersey org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java org.springframework.boot spring-boot-devtools true org.springframework.boot spring-boot-maven-plugin
找到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 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 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 getAllArticles() {
String hql = "FROM Article as atcl ORDER BY atcl.articleId";
return (List) 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 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 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 list = details.request(MediaType.APPLICATION_JSON)
.get(new GenericType>() {});
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



