Добро пожаловать на учебник по RESTful веб-сервисам на Java. REST – это аббревиатура для REpresentational State Transfer. REST – это архитектурный стиль разработки приложений, к которым можно получить доступ через сеть. Архитектурный стиль REST был представлен Роем Филдингом в его докторской диссертации в 2000 году.
Restful веб-сервисы
Restful веб-сервисы – это архитектура бессостоятельного клиент-сервера, где веб-сервисы являются ресурсами и могут быть идентифицированы по их URI. Клиентские приложения REST могут использовать методы HTTP GET/POST для вызова Restful веб-сервисов. REST не определяет какой-либо конкретный протокол для использования, но в большинстве случаев он используется через HTTP/HTTPS. По сравнению с веб-сервисами SOAP, они легковесные и не следуют каким-либо стандартам. Мы можем использовать XML, JSON, текст или любой другой тип данных для запроса и ответа.
Java API для RESTful веб-сервисов
Java API для RESTful веб-сервисов (JAX-RS) – это Java API для создания REST веб-сервисов. JAX-RS использует аннотации для упрощения разработки и развертывания веб-сервисов. JAX-RS является частью JDK, поэтому вам не нужно включать что-либо, чтобы использовать его аннотации.
Аннотации Restful веб-сервисов
Некоторые из важных аннотаций JAX-RS:
@Path
: используется для указания относительного пути класса и методов. Мы можем получить URI веб-сервиса, просканировав значение аннотации Path.@GET
,@PUT
,@POST
,@DELETE
и@HEAD
: используются для указания типа HTTP-запроса для метода.@Produces
,@Consumes
: используются для указания типов запроса и ответа.@PathParam
: используется для привязки параметра метода к значению пути путем его анализа.
Restful веб-сервисы и SOAP
- SOAP – это протокол, в то время как REST – это архитектурный стиль.
- Приложения сервера и клиента SOAP тесно связаны и привязаны к контракту WSDL, в то время как в веб-сервисах REST и клиенте нет контракта.
- Кривая обучения для REST проще по сравнению с веб-сервисами SOAP.
- Типы запросов и ответов в веб-сервисах REST могут быть XML, JSON, текст и т. д., в то время как SOAP работает только с XML.
- JAX-RS – это Java API для веб-сервисов REST, в то время как JAX-WS – это Java API для веб-сервисов SOAP.
Реализации REST API
Существует две основные реализации JAX-RS API.
- Jersey: Jersey является эталонной реализацией, предоставляемой Sun. Для использования Jersey в качестве нашей реализации JAX-RS нам просто нужно настроить его сервлет в файле web.xml и добавить необходимые зависимости. Обратите внимание, что API JAX-RS является частью JDK, а не Jersey, поэтому мы должны добавить его зависимости в наше приложение.
- RESTEasy: RESTEasy – это проект JBoss, который предоставляет реализацию JAX-RS.
Руководство по созданию Java-RESTful веб-сервисов
Давайте посмотрим, насколько просто создать RESTful веб-сервис с использованием Jersey, а затем RESTEasy. Мы будем предоставлять следующие методы через 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 веб-сервисы
Создайте динамический веб-проект, а затем преобразуйте его в Maven, чтобы получить каркас вашего проекта веб-сервисов. Ниже показана структура проекта финального проекта. Давайте рассмотрим зависимости Jersey, которые у нас есть в файле pom.xml.
<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 для вызова веб-службы REST с использованием Jersey, то это необходимо. Теперь давайте посмотрим на файл развертывания, чтобы узнать, как настроить Jersey для создания нашего веб-приложения.
<?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 к нашему веб-приложению; в нашем коде Java мы будем использовать аннотации JAX-RS. Обратите внимание на значение инициализационного параметра com.sun.jersey.config.property.packages
, чтобы указать пакет, который будет сканироваться для ресурсов и методов веб-службы.
Пример модельных классов REST
Прежде всего мы создадим две модельные бины – Person
для данных нашего приложения и Response
для отправки ответа системам клиентов. Поскольку мы будем отправлять XML-ответ, бины должны быть аннотированы с помощью @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
На основе структуры нашего 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 веб-сервисов
Вот и всё. Наш веб-сервис готов, просто экспортируйте его в виде файла WAR и поместите в каталог веб-приложений Tomcat или разверните в любом другом контейнере по вашему выбору. Ниже приведены некоторые тесты, выполненные с использованием расширения Postman для браузера Chrome для этого веб-сервиса. Обратите внимание, что в заголовке запроса мы должны указать значения Accept и Content-Type как “application/xml”, как показано на изображении ниже.
Вот и все для создания веб-сервисов с использованием реализации Jersey JAX-RS. Как вы можете видеть, большая часть кода использует аннотации JAX-RS, а Jersey подключается через дескриптор развертывания и зависимости.
Пример веб-сервисов RESTEasy RESTful
Мы будем использовать всю бизнес-логику, разработанную в проекте Jersey, но вместо внесения изменений в тот же проект, я создал новый проект. Создайте динамический веб-проект и преобразуйте его в проект Maven. Затем скопируйте все java-классы – Person, Response, PersonService и PersonServiceImpl. Ниже представлен конечный проект после завершения всех изменений. Добавьте зависимости RESTEasy ниже в файл pom.xml.
<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>
Ниже приведен файл web.xml, где мы настраиваем сервлет Resteasy.
<?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>
Обратите внимание на параметр инициализации, где мы указываем класс 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
Вот и всё. Наш веб-сервис готов с реализацией RESTEasy JAX-RS. Ниже приведены некоторые результаты тестирования с помощью расширения Postman для Chrome.
Это все для Учебного пособия по Restful веб-сервисам. Надеюсь, вы узнали о аннотациях JAX-RS и поняли преимущества использования стандартного API, которое помогло нам в повторном использовании кода и переходе от Jersey к RESTEasy так легко.
Source:
https://www.digitalocean.com/community/tutorials/restful-web-services-tutorial-java