Jersey Java 教程
欢迎来到 Java Jersey 教程。最近我开始使用 JAX-RS Jersey 框架开发一个 Restful Web 服务项目。
什么是 Java Jersey 框架?
Java Jersey 项目跟踪 JAX-RS API,用于用 Java 创建 Restful Web 服务。
1. 谁应该使用本教程?
本教程适用于有兴趣使用 JAX-RS API 和 JAXB 开发和部署 Restful Web 服务的 Java 程序员。
2. 先决条件
本教程的范围是使用 Jersey API 创建 Restful Web 服务,使用 Java 客户端程序调用 Web 服务,并使用该工具测试 Web 服务。需要对 Java、Web 服务、XML、Maven 和任何应用程序服务器 (JBoss/Tomcat) 有基本的了解才能轻松理解本教程。
3. 软件和工具
- JDK 版本 1.8.0_131
- Apache Maven 3.5.3
- Mac OS X 10.13.4
- Tomcat 8.5.16
- Eclipse Java EE IDE 氧气 4.7.3
创建 Jersey Eclipse Maven 项目
在 Eclipse 中创建一个“动态 Web 项目”,然后将其转换为 maven 项目。这将为我们提供一个基于 maven 的 Web 应用程序基本项目。我已将 GroupId 指定为,com.journaldev.jersey
并将 artifactID 指定为,my-jersey-project
但您可以指定任何您喜欢的内容。一旦我们完成项目的开发,项目结构将如下图所示。
Java Jersey Restful Web 服务项目说明
1. pom.xml:项目配置详情,注意提供的jersey依赖项,其他详情对于任何类似的maven项目都是通用的。
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.jersey</groupId>
<artifactId>my-jersey-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.14</version>
</dependency>
</dependencies>
<build>
<finalName>My-Jersey-Project</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. EmpRequest.java:请求对象的 Java Bean。这里要注意的重要一点是@XmlRootElement
将类映射到 XML 元素的注释。
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "empRequest")
public class EmpRequest {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3. EmpResponse.java:响应对象的 Java bean。
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "empResponse")
public class EmpResponse {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4. ErrorResponse.java:发生异常时将作为响应发送的 Java Bean。
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "errorResponse")
public class ErrorResponse {
private String errorCode;
private int errorId;
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public int getErrorId() {
return errorId;
}
public void setErrorId(int errorId) {
this.errorId = errorId;
}
}
5.EmpNotFoundException.java:Web服务中抛出的正常异常类。
package com.journaldev.exception;
public class EmpNotFoundException extends Exception {
private static final long serialVersionUID = 4351720088030656859L;
private int errorId;
public int getErrorId() {
return errorId;
}
public EmpNotFoundException(String msg, int errorId) {
super(msg);
this.errorId = errorId;
}
public EmpNotFoundException(String msg, Throwable cause) {
super(msg, cause);
}
}
6. web.xml:Web 服务的部署描述符。因此,任何带有 URI 的请求https://<HOST>:<PORT>/My-Jersey-Project/rest/*
都将由 Jersey ServletContainer servlet 处理。传递给“com.sun.jersey.config.property.packages”的 init-param 值定义了 jersey 将查找 Web 服务类的包。此属性必须指向您的资源类。它还会在子包中查找资源类。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns="https://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>My Jersey Project</display-name>
<!-- Jersey Servlet configurations -->
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.journaldev</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- Jersey Servlet configurations -->
</web-app>
7. EmpRouter.java:处理不同类型请求的资源类。
- @Path (“/emp”) - 所有带有 URI 的请求都
https://<HOST>:<PORT>/My-Jersey-Project/rest/emp/
将由此资源类处理。 - @Path (“/getEmp”) - 所有带有 URI 的请求都
https://<HOST>:<PORT>/My-Jersey-Project/rest/emp/getEmp
将通过此方法处理。 - @POST - 此注释定义使用的 HTTP 方法应为 POST。其他一些可能的值是@GET、@PUT、@DELETE
- @Consumes (MediaType.APPLICATION_XML) - 该方法接受 XML 元素
- @Produces (MediaType.APPLICATION_XML) - 该方法返回 XML 元素
package com.journaldev.router;
import com.journaldev.exception.EmpNotFoundException;
import com.journaldev.model.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBElement;
@Path("/emp")
public class EmpRouter {
@POST
@Path("/getEmp")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public Response getEmp(JAXBElement<EmpRequest> empRequest)
throws EmpNotFoundException {
EmpResponse empResponse = new EmpResponse();
if (empRequest.getValue().getId() == 1) {
empResponse.setId(empRequest.getValue().getId());
empResponse.setName(empRequest.getValue().getName());
} else {
throw new EmpNotFoundException("Wrong ID", empRequest.getValue()
.getId());
}
return Response.ok(empResponse).build();
}
}
8. EmpNotFoundExceptionMapper.java:将 EmpNotFoundException 映射到 Response 对象的异常映射器类。该类应具有@Provider注释。该类应位于 web.xml 中为资源类提供的包中。toResponse()
方法的实现生成 ErrorResponse 对象并将其设置为 Response 对象中的实体,状态为 INTERNAL_SERVER_ERROR。
package com.journaldev.exceptionmapper;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import com.journaldev.exception.EmpNotFoundException;
import com.journaldev.model.ErrorResponse;
@Provider
public class EmpNotFoundExceptionMapper implements
ExceptionMapper<EmpNotFoundException> {
public EmpNotFoundExceptionMapper() {
}
public Response toResponse(
EmpNotFoundException empNotFoundException) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrorId(empNotFoundException.getErrorId());
errorResponse.setErrorCode(empNotFoundException.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
errorResponse).type(
MediaType.APPLICATION_XML).build();
}
}
我们的 Web 服务已经准备就绪,只需构建它以创建 WAR 文件并将其部署到应用程序服务器。
Jersey 客户端示例
我们可以使用 Jersey Client 来调用我们的 Web 服务并以编程方式获取响应。EmpClient.java :这是一个示例 Java 程序,通过它可以调用我们的 Web 服务。我们使用 Jersey Client API 来调用服务,并根据响应状态将响应实体解析为 EmpResponse 或 ErrorResponse 类。
package com.journaldev.client;
import javax.ws.rs.core.MediaType;
import com.journaldev.model.EmpRequest;
import com.journaldev.model.EmpResponse;
import com.journaldev.model.ErrorResponse;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
public class EmpClient {
/**
* @param args
*/
public static void main(String[] args) {
String uri = "https://localhost:8080/My-Jersey-Project/rest/emp/getEmp";
EmpRequest request = new EmpRequest();
// set id as 1 for OK response
request.setId(2);
request.setName("PK");
try {
Client client = Client.create();
WebResource r = client.resource(uri);
ClientResponse response = r.type(MediaType.APPLICATION_XML).post(ClientResponse.class, request);
System.out.println(response.getStatus());
if (response.getStatus() == 200) {
EmpResponse empResponse = response.getEntity(EmpResponse.class);
System.out.println(empResponse.getId() + "::" + empResponse.getName());
} else {
ErrorResponse exc = response.getEntity(ErrorResponse.class);
System.out.println(exc.getErrorCode());
System.out.println(exc.getErrorId());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
成功响应 错误响应
概括
在这篇文章中,我们学习了如何使用 Jersey API 创建 REST Web 服务。我们还研究了 Jersey 客户端如何通过 Java 程序调用我们的 REST API。
您可以从我们的GitHub 存储库中检出完整的项目代码。