欢迎来到Java的Restful Web服务教程。REST是表征状态转移的首字母缩写。REST是一种用于开发可以通过网络访问的应用程序的架构风格。REST架构风格是由Roy Fielding在他的博士论文中于2000年提出的。
Restful Web服务
Restful Web服务是一种无状态客户端-服务器架构,其中Web服务是资源,并可通过其URI进行标识。REST客户端应用程序可以使用HTTP GET/POST方法调用Restful Web服务。REST不指定使用任何特定的协议,但在几乎所有情况下都是通过HTTP/HTTPS使用的。与SOAP Web服务相比,这些服务更轻量级且不遵循任何标准。我们可以使用XML、JSON、文本或任何其他类型的数据进行请求和响应。
Java RESTful Web服务API
Java RESTful Web服务(JAX-RS)是用于创建REST Web服务的Java API。JAX-RS使用注解来简化Web服务的开发和部署。JAX-RS是JDK的一部分,因此您无需包含任何内容即可使用其注解。
Restful Web Services Annotations
一些重要的 JAX-RS 注解包括:
@Path
:用于指定类和方法的相对路径。我们可以通过扫描 Path 注解的值来获取 Web 服务的 URI。@GET
、@PUT
、@POST
、@DELETE
和@HEAD
:用于指定方法的 HTTP 请求类型。@Produces
、@Consumes
:用于指定请求和响应的类型。@PathParam
:通过解析将方法参数绑定到路径值。
Restful Web Services and SOAP
- SOAP 是一种协议,而 REST 是一种架构风格。
- SOAP 服务器和客户端应用程序紧密耦合,并与 WSDL 合同绑定,而 REST Web 服务和客户端没有合同。
- 与 SOAP Web 服务相比,学习曲线对于 REST 来说更容易。
- REST Web 服务的请求和响应类型可以是 XML、JSON、文本等,而 SOAP 只能使用 XML。
- JAX-RS 是用于 REST Web 服务的 Java API,而 JAX-WS 是用于 SOAP Web 服务的 Java API。
REST API 实现
有两种主要的 JAX-RS API 实现。
- Jersey:Jersey 是 Sun 提供的参考实现。要将 Jersey 用作我们的 JAX-RS 实现,我们只需要在 web.xml 中配置其 servlet 并添加所需的依赖项。请注意,JAX-RS API 是 JDK 的一部分,而不是 Jersey,因此我们必须在我们的应用程序中添加其依赖 jar 包。
- RESTEasy:RESTEasy 是提供 JAX-RS 实现的 JBoss 项目。
Java RESTful Web 服务教程
让我们看看使用 Jersey 和 RESTEasy 创建 RESTful Web 服务有多容易。我们将在 HTTP 上公开以下方法,并使用 Chrome Postman 扩展来测试它们。
URI | HTTP Method | Description |
---|---|---|
/person/{id}/getDummy | GET | Returns a dummy person object |
/person/add | POST | Adds a person |
/person/{id}/delete | GET | Delete the person with ‘id’ in the URI |
/person/getAll | GET | Get all persons |
/person/{id}/get | GET | Get the person with ‘id’ in the URI |
Jersey RESTful Web 服务
创建一个动态网页项目,然后将其转换为Maven,以获得您的Web服务项目的框架。下图显示了最终项目的项目结构。让我们看看在pom.xml文件中我们拥有的Jersey依赖项。
<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>JAXRS-Example</groupId>
<artifactId>JAXRS-Example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
我们不需要添加jersey-client依赖项,但如果您正在编写使用Jersey调用REST Web服务的Java程序,则需要。现在让我们查看部署描述符,了解如何配置Jersey以创建我们的Web应用程序。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>JAXRS-Example</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>/*</url-pattern>
</servlet-mapping>
<!-- Jersey Servlet configurations -->
</web-app>
这就是将Jersey插入我们的Web应用程序所需的全部内容,在我们的Java代码中,我们将使用JAX-RS注解。注意init参数com.sun.jersey.config.property.packages
的值,用于提供将被扫描以寻找Web服务资源和方法的包。
REST示例模型类
首先,我们将创建两个模型bean – Person
用于我们的应用程序数据和Response
用于向客户端系统发送响应。由于我们将发送XML响应,因此这些bean应该带有@XmlRootElement
注解,因此我们有了这个类。
package com.journaldev.jaxrs.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement (name="person")
public class Person {
private String name;
private int age;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString(){
return id+"::"+name+"::"+age;
}
}
package com.journaldev.jaxrs.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Response {
private boolean status;
private String message;
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
REST Web服务教程服务
根据我们的URI结构,以下是服务接口及其实现代码。
package com.journaldev.jaxrs.service;
import com.journaldev.jaxrs.model.Person;
import com.journaldev.jaxrs.model.Response;
public interface PersonService {
public Response addPerson(Person p);
public Response deletePerson(int id);
public Person getPerson(int id);
public Person[] getAllPersons();
}
package com.journaldev.jaxrs.service;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.journaldev.jaxrs.model.Person;
import com.journaldev.jaxrs.model.Response;
@Path("/person")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class PersonServiceImpl implements PersonService {
private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
@Override
@POST
@Path("/add")
public Response addPerson(Person p) {
Response response = new Response();
if(persons.get(p.getId()) != null){
response.setStatus(false);
response.setMessage("Person Already Exists");
return response;
}
persons.put(p.getId(), p);
response.setStatus(true);
response.setMessage("Person created successfully");
return response;
}
@Override
@GET
@Path("/{id}/delete")
public Response deletePerson(@PathParam("id") int id) {
Response response = new Response();
if(persons.get(id) == null){
response.setStatus(false);
response.setMessage("Person Doesn't Exists");
return response;
}
persons.remove(id);
response.setStatus(true);
response.setMessage("Person deleted successfully");
return response;
}
@Override
@GET
@Path("/{id}/get")
public Person getPerson(@PathParam("id") int id) {
return persons.get(id);
}
@GET
@Path("/{id}/getDummy")
public Person getDummyPerson(@PathParam("id") int id) {
Person p = new Person();
p.setAge(99);
p.setName("Dummy");
p.setId(id);
return p;
}
@Override
@GET
@Path("/getAll")
public Person[] getAllPersons() {
Set<Integer> ids = persons.keySet();
Person[] p = new Person[ids.size()];
int i=0;
for(Integer id : ids){
p[i] = persons.get(id);
i++;
}
return p;
}
}
大部分代码都是不言自明的,请花些时间熟悉JAX-RS注解@Path
、@PathParam
、@POST
、@GET
、@Consumes
和@Produces
。
Restful Web服务测试
就这样。我们的Web服务已经准备好,只需将其导出为WAR文件并放入Tomcat的webapps目录,或部署到您选择的任何其他容器中。以下是使用Postman Chrome扩展程序对此Web服务执行的一些测试。请注意,如下图所示,我们必须在请求头中提供”application/xml”作为Accept和Content-Type的值。
这就是使用Jersey JAX-RS实现创建Web服务的全部内容。正如您所看到的,大部分代码都是使用JAX-RS注解编写的,而Jersey是通过部署描述符和依赖项插入的。
RESTEasy RESTful Web Services Example
我们将使用在Jersey项目中开发的所有业务逻辑,但与对同一项目进行更改不同,我已经创建了一个新项目。创建一个动态Web项目并将其转换为Maven项目。然后复制所有Java类 – Person、Response、PersonService和PersonServiceImpl。在我们完成所有更改后,下面是最终的项目。在pom.xml文件中添加以下RESTEasy依赖项。
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.13.Final</version>
</dependency>
以下是我们正在配置Resteasy servlet的web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>JAXRS-Example-RestEasy</display-name>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.journaldev.jaxrs.resteasy.app.MyApp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
请注意,init-param中我们提供了MyApp类作为值,在这里我们扩展了javax.ws.rs.core.Application类,如下所示。
package com.journaldev.jaxrs.resteasy.app;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
import com.journaldev.jaxrs.service.PersonServiceImpl;
public class MyApp extends Application {
private Set<Object> singletons = new HashSet<Object>();
public MyApp() {
singletons.add(new PersonServiceImpl());
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
RESTEasy Web Services Test
就这样。我们的Web服务已经准备好使用RESTEasy JAX-RS实现。以下是来自Postman Chrome扩展测试的一些输出。
。这就是Restful Web Services教程的全部内容,希望您了解了JAX-RS注解并理解了拥有标准API的好处,这有助于我们重复使用代码并轻松地从Jersey迁移到RESTEasy。
Source:
https://www.digitalocean.com/community/tutorials/restful-web-services-tutorial-java