Java的Restful Web Services教程
欢迎使用Java的Restful Web服务教程。
REST是代表状态转移的首字母缩写。
REST是一种体系结构样式,用于开发可通过网络访问的应用程序。
REST建筑风格是由Roy Fielding在2000年的博士论文中提出的。
Restful Web服务
Restful Web Services是一种无状态的客户端-服务器体系结构,其中Web服务是资源,可以通过其URI进行标识。
REST客户端应用程序可以使用HTTP GET/POST方法来调用Restful Web服务。
REST没有指定要使用的任何特定协议,但是在几乎所有情况下,它都是通过HTTP/HTTPS使用的。
与SOAP Web服务相比,它们是轻量级的,不遵循任何标准。
我们可以使用XML,JSON,文本或者任何其他类型的数据进行请求和响应。
Java RESTful Web服务API
RESTful Web服务的Java API(JAX-RS)是用于创建REST Web服务的Java API。
JAX-RS使用注释来简化Web服务的开发和部署。
JAX-RS是JDK的一部分,因此您无需添加任何内容即可使用其注释。
Restful Web服务注释
一些重要的JAX-RS批注是:
@Path:用于指定类和方法的相对路径。
我们可以通过扫描路径注释值来获取Web服务的URI。@ GET,@ PUT,@ POST,@ DELETE和@HEAD:用于指定方法的HTTP请求类型。
@ Produces,@ Consumes:用于指定请求和响应类型。
@PathParam:用于通过解析将方法参数绑定到路径值。
Restful Web服务和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有两种主要实现。
泽西岛:泽西岛是Sun提供的参考实现。
为了使用Jersey作为我们的JAX-RS实现,我们需要在web.xml中配置其servlet并添加所需的依赖项。
请注意,JAX-RS API是JDK而不是Jersey的一部分,因此我们必须在应用程序中添加其依赖项jar。RESTEasy:RESTEasy是提供JAX-RS实现的JBoss项目。
Java Restful Web服务教程
让我们看看使用Jersey和RESTEasy创建Restful网络服务有多么容易。
我们将通过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服务
创建一个动态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依赖关系,但是如果您正在编写Java程序以使用Jersey调用REST网络服务,则需要这样做。
现在,让我们看一下部署描述符,以了解如何配置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.theitroad</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响应,因此应使用@ XmlRootElement来标注Bean,因此我们拥有此类。
package com.theitroad.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.theitroad.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.theitroad.jaxrs.service;
import com.theitroad.jaxrs.model.Person;
import com.theitroad.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.theitroad.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.theitroad.jaxrs.model.Person;
import com.theitroad.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目录中或者部署到您选择的任何其他容器中即可。
以下是针对此Web服务使用Postman chrome扩展程序执行的一些测试。
请注意,我们必须在请求标头中提供Accept和Content-Type值作为" application/xml",如下图所示。
- getDummy
- add
- get
- getAll
- delete
这就是使用Jersey JAX-RS实施创建网络服务的全部过程。
如您所见,大多数代码都使用JAX-RS注释,并且Jersey通过部署描述符和依赖项插入。
RESTEasy RESTful Web服务示例
我们将使用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.theitroad.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.theitroad.jaxrs.resteasy.app;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
import com.theitroad.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服务测试
RESTEasy JAX-RS实现已准备好我们的Web服务。
以下是Postman chrome扩展测试的一些输出。
- getDummy
- add
- get

