Статьи

Разработка веб-сервисов Restful с использованием Spring MVC

ОТДЫХ ВВЕДЕНИЕ

Из Википедии: Архитектура в стиле REST состоит из клиентов и серверов. Клиенты инициируют запросы к серверам; серверы обрабатывают запросы и возвращают соответствующие ответы. Запросы и ответы строятся вокруг передачи представлений ресурсов. Ресурс может быть, по существу, любым последовательным и значимым понятием, к которому можно обратиться.

Как вы уже прочли, в архитектуре Rest самое важное — это наличие ресурса. Этот ресурс может быть любым (обычно запрашиваемая клиентом информация), который может быть идентифицирован с помощью глобального идентификатора ( URI в случае HTTP ). Чтобы манипулировать этими ресурсами, клиент взаимодействует с использованием стандартных интерфейсов (например, HTTP ) и обменивается представлениями этих ресурсов (используя HTML , XML и т. Д.).
Обратите внимание, что Rest не заставляет вас использовать какой-либо конкретный сетевой протокол или способ определения ресурсов.

Для тех, кто никогда не читал об отдыхе, это описание архитектуры отдыха может показаться странным и немного сложным.

Веб-сервис RESTful — это простой веб-сервис, реализованный с использованием HTTP и принципов REST . URI определяется как глобально идентифицированный, интерфейс связи — HTTP, а представление ресурса может быть любым допустимым типом медиа-данных в Интернете, например, JSON , XML или YAML . Набор операций, которые могут быть выполнены с ресурсами, зависит от методов HTTP и является ( GET — получение / перечисление, PUT — замена / обновление, POST — создание и DELETE — удаление).
РУКИ ПО РАБОТЕ
Давайте создадим наше первое приложение Rest с помощью Spring MVC . Представьте себе приложение, которое имеет базу данных символов манга, и вы хотите предоставить интерфейс Rest, чтобы клиенты могли получать символы, следуя стратегии RESTful .
Первое, что нужно сделать, это определить ресурс. В этом случае это просто « персонаж ». Следующим шагом является поиск URI, который однозначно определяет символ. Легкое слишком де-факто правило может быть применено здесь. Это правило предполагает, что уникальным URI может быть <host> / <applicationname> / <resourceName> s / <id>, в нашем случае для возврата ( GET ) символа с идентификатором 1 URI будет « http: // localhost: 8080 / RestServer / characters / 1 “. Если идентификатор отсутствует, все символы должны быть восстановлены. Если вместо GET используется POST , будет вставлен символ с идентификатором «1». И, наконец, решите, какой тип мультимедиа в Интернете требуется, в этом случае это не имеет значения, потому что мы реализуем и клиент, и сервер, поэтому изначально будет использоваться XML .
КОДИРОВАНИЕ
Начнем с простого приложения Spring MVC, созданного с помощью шаблона Spring MVC . Не секрет, что здесь у вас будет файл servlet-context.xml, в котором регистрируются компонентное сканирование , управляемое аннотациями и InternalResourceViewResolver .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8" ?>
 <!--  DispatcherServlet Context: defines this servlet's request-processing
  infrastructure
  -->
 <!--  Enables the Spring MVC @Controller programming model
  -->
 
  <annotation-driven />
 
 <!--  Resolves views selected for rendering by @Controllers to .jsp resources
  in the /WEB-INF/views directory
  -->
 
 <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <beans:property name="prefix" value="/WEB-INF/views/" />
  <beans:property name="suffix" value=".jsp" />
 </beans:bean>
 
  <context:component-scan base-package="org.springframework.rest" />
</beans:beans>

Следующим шагом является определение класса символов . Простой POJO с четырьмя атрибутами. Класс преобразуется в его представление XML с помощью аннотации Jaxb . Jaxb позволяет разработчикам отображать классы Java в представления XML и наоборот.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package org.springframework.rest;
 
import java.net.URL;
 
import org.codehaus.jackson.annotate.JsonAutoDetect;
 
 
@XmlRootElement
public final class Character {
 
 private  int id;
 private  String name;
 private  boolean isHuman;
 private URL characterUrl;
 
 protected Character() {
 
 }
 
 public Character(int id, String name, boolean isHuman, URL characterUrl) {
  super();
  this.id = id;
  this.name = name;
  this.isHuman = isHuman;
  this.characterUrl = characterUrl;
 }
 
 
 
 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;
 }
 
 public boolean isHuman() {
  return isHuman;
 }
 
 public void setHuman(boolean isHuman) {
  this.isHuman = isHuman;
 }
 
 
 public URL getCharacterUrl() {
  return characterUrl;
 }
 
 public void setCharacterUrl(URL characterUrl) {
  this.characterUrl = characterUrl;
 }
 
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + id;
  return result;
 }
 
 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Character other = (Character) obj;
  if (id != other.id)
   return false;
  return true;
 }
 
 
}

И, наконец, самый важный класс в Spring MVC — « Контроллер ». Контроллер будет нести ответственность за выполнение необходимых операций ресурса персонажа . В текущем случае реализован только GET , остальные операции будут аналогичными. Давайте посмотрим код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Controller
public class HomeController {
 
 
 private static final Map<Integer, Character> characters = new HashMap<Integer, Character>();
 
 static {
  try {
   characters.put(1, new Character(1, "Totoro", false, new URL("http://animeonly.org/albums/VISINAUJI/EGIO/fourth/Mon-Voisin-Totoro/normal_totoro_001.jpg")));
   characters.put(2, new Character(2, "Satsuki Kusakabe", true, new URL("http://profile.ak.fbcdn.net/hprofile-ak-ash2/48980_1802552968_7286_n.jpg")));
   characters.put(3, new Character(3, "Therru", false, new URL("http://28.media.tumblr.com/tumblr_lj4ctjKA8Y1qdvyqpo1_400.jpg")));
  } catch (MalformedURLException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * Simply selects the home view to render by returning its name.
  */
 @RequestMapping(value = "/characters/{characterId}", method = RequestMethod.GET)
 @ResponseBody
 public Character findCharacter(@PathVariable int characterId) {
  return characters.get(characterId);
 
 
 }
 
}

Первая часть — это карта, где хранятся все персонажи. Я использовал этот подход, чтобы не фокусироваться на доступе к данным. Затем метод findCharacter, который вызывается, когда URI равен / characters / {characterId }. Это шаблон URI и строка, подобная URI , содержащая одно или несколько имен переменных, доступ к которым можно получить с помощью аннотации @PathVariable . Поэтому, когда вы обращаетесь к параметру / characters / 1, characterId привязывается к 1.

Последняя важная часть — аннотация @ResponseBody . Эта аннотация может быть наложена на метод и указывает, что возвращаемый тип должен быть записан прямо в тело ответа HTTP , а не помещен в модель или интерпретирован как имя представления как стандартное поведение Spring MVC . Поэтому метод findCharacter возвращает объект Character .

И это все, если вы выполните этот код, и, например, введете URI http: // localhost: 8080 / RestServer / characters / 1, вывод (с использованием RestClient UI ) будет:

А теперь, когда вам интересно, ¿Если я возвращаю объект Character и выводим XML , где происходит преобразование между объектом и XML ? Так просто, позвольте мне представить новую концепцию: HttpMessageConverters . HttpMessageConverter отвечает за преобразование сообщения HTTP- запроса в объект и преобразование объекта в тело ответа HTTP . Далее HttpMessageConverters регистрируются по умолчанию:

— ByteArrayHttpMessageConverter
— StringHttpMessageConverter
— ResourceHttpMessageConverter
— SourceHttpMessageConverter
— XmlAwareHttpMessageConverter
— Jaxb2RootElementHttpMessageConverter
— MappingJacksonHttpMessageConverter
Итак, теперь вы понимаете, почему работает отлично. Когда вы возвращаете экземпляр Character , Jaxb2RootElementHttpMessageConverter с помощью метода canWrite проверяет, содержит ли класс аннотацию XmlRootElement . Если класс аннотирован, вызывается метод write. В этом случае вызывается Jaxb marshaller, и возвращается XML . То же самое из XML в объект, но с использованием класса unmarshaller Jaxb .
Это так просто, без сложных конфигураций, без сложных отображений, без неясного кода, и вам нужно беспокоиться только о объектах модели, а не о преобразовании. Но позвольте мне представить одно изменение. Теперь вместо возврата XML мы хотим вернуть JSON .
Изменить не может быть проще, добавьте библиотеку Джексона в pom.xml и измените @XmlRootElement на @JsonAutoDetect . И теперь MappingJacksonHttpMessageConverter будет обрабатывать этот объект и преобразует экземпляр Character в протокол JSON с использованием библиотеки Джексона . Изменение только одной строки кода !!!
И теперь вывод будет:

ВЫВОДЫ

Конечно, это очень простое приложение с одной операцией, но оно дает вам представление о том, как разрабатывать веб-службы Restful с использованием Spring MVC . Это вопрос времени написания всех ваших необходимых операций, используя тот же подход, который я использовал с GET .

Придя в этот момент, я думаю, что все мы пришли к одинаковому выводу. Аннотации действительно мощные, и Spring MVC идеально подходит для разработки веб- сервисов RESTful .

Увидимся в следующий раз…

Скачать код.

Ссылка: Разработайте веб-службы Restful с использованием Spring MVC от нашего партнера по JCG Алекса Сото в блоге One Jar To Rule All .

Статьи по Теме :