У цьому розділі коротко описані опції, доступні в spring-test для програм Spring MVC.

  • Фіктивні об'єкти Servlet API: Фіктивні реалізації контрактів Servlet API для модульного тестування контролерів, фільтрів та інших вебкомпонентів.

  • TestContext Framework: Підтримка завантаження конфігурації Spring у тестах JUnit та TestNG, включно з ефективним кешуванням завантаженої конфігурації в тестових методах та підтримкою завантаження WebApplicationContext з MockServletContext.

  • Spring MVC Test: Фреймворк, також відомий як MockMvc, призначений для тестування анотованих контролерів через DispatcherServlet (тобто підтримує анотації), в комплекті з інфраструктурою Spring MVC, але без HTTP-сервера.

  • REST на стороні клієнта: spring-test надає MockRestServiceServer, який можна використовувати як фіктивний сервер для тестування коду на стороні клієнта, що на внутрішньому рівні використовує RestTemplate .

  • WebTestClient: Створений для тестування програм WebFlux, але може також використовуватися для наскрізного інтеграційного тестування на будь-якому сервері через HTTP-з'єднання. Це неблокуючий, реактивний клієнт, який добре підходить для тестування у сценаріях асинхронної роботи та потокової передачі.

Веб-сокети протоколу WebSocket

Ця частина довідкової документації охоплює підтримку стека сервлетів, обмін повідомленнями через WebSocket, що включає необроблені взаємодії WebSocket, емуляцію WebSocket через SockJS та обмін повідомленнями "публікація-підписка" через STOMP як субпротокол поверх WebSocket.

Вступ до протоколу WebSocket

Протокол WebSocket, RFC 6455, передбачає стандартизований спосіб встановлення повнодуплексного двостороннього каналу зв'язку між клієнтом та сервером поверх одного TCP-з'єднання. Це відмінний від HTTP протокол TCP, але призначений для роботи поверх HTTP, використовує порти 80 і 443 і дозволяє повторно використовувати існуючі правила брандмауера.

Взаємодія WebSocket починається з HTTP-запиту, який використовує заголовок HTTP Upgrade для оновлення або, в цьому випадку, для переходу на протокол WebSocket. У цьому прикладі показано таку взаємодію:

GET /spring-websocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: websocket 
Connection: Upgrade 
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080
  1. Заголовок Upgrade.
  2. Використання з'єднання Upgrade.

Замість звичайного коду стану 200 сервер із підтримкою WebSocket видає повідомлення, схоже на наступне:

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp
  1. Перемикач протоколів

Після успішного підтвердження встановлення зв'язку сокет TCP, що лежить в основі запиту на оновлення HTTP, залишається відкритим, щоб клієнт та сервер могли продовжувати надсилати та отримувати повідомлення.

Повноцінний вступ до роботи вебсокетів WebSocket виходить за межі цього документа. Див. "RFC 6455": розділ, присвячений WebSocket в HTML5, або будь-який з численних описів та навчальних посібників в інтернеті.

Зверни увагу, що якщо сервер WebSocket працює за веб-сервером (наприклад, nginx), то, швидше за все, потрібно налаштувати його на передачу запитів на оновлення WebSocket серверу. Аналогічно, якщо програма працює у хмарному середовищі, перевір інструкції постачальника хмарних послуг щодо підтримки WebSocket.

HTTP проти WebSocket

Незважаючи на те, що протокол WebSocket розроблений як HTTP-сумісний і виходить з HTTP-запиту, важливо розуміти, що ці два протоколи спричиняють абсолютно різні архітектури та моделі програмування додатків.

У HTTP та REST програма моделюється як множина URL-адрес. Щоб взаємодіяти з програмою, клієнти звертаються до цих URL-адрес у стилі "запит-відповідь". Сервери надсилають запити до відповідного обробника на основі URL-адреси, методу та заголовків HTTP.

Натомість у вебсокетах WebSocket для початкового підключення зазвичай використовується лише одна URL-адреса. Згодом всі повідомлення програми передаються цим же TCP-з'єднанням. Це вказує на зовсім іншу асинхронну, керовану подіями архітектуру обміну повідомленнями.

WebSocket також є низькорівневим транспортним протоколом, який, на відміну від HTTP, не передбачає жодної семантики вмісту повідомлень. Це означає, що не існує способу маршрутизації або обробки повідомлення, доки між клієнтом та сервером не буде узгоджено семантику повідомлення.

Клієнти та сервери на WebSocket можуть узгодити використання протоколу обміну повідомленнями вищого рівня (наприклад, STOMP) за допомогою заголовка Sec-WebSocket-Protocol у HTTP-запиті підтвердження встановлення зв'язку. Без цього їм потрібно придумати свої власні угоди.

Коли слід використовувати вебсокети протоколу WebSocket?

Вебсокети протоколу WebSocket можуть зробити вебсторінку динамічною та інтерактивною. Однак у багатьох випадках поєднання Ajax і HTTP-потоку або довгого полінгу (опитування) може бути простим та ефективним рішенням.

Наприклад, новини, пошта та соціальні стрічки мають оновлюватися динамічно, але цілком допустимо робити це раз на кілька хвилин. З іншого боку, програми для спільної роботи, ігри та фінансові програми повинні частіше працювати в реальному часі.

Сама по собі затримка не є вирішальним фактором. Якщо обсяг повідомлень відносно невеликий (наприклад, при моніторингу мережних збоїв), ефективним рішенням може стати потокова передача або полінг за протоколом HTTP. Саме поєднання низької затримки, високої частоти та великого обсягу є найкращим аргументом на користь використання WebSocket.

Пам'ятай також, що в інтернеті обмежувальні проксі-сервери, які знаходяться поза твоїм контролем, можуть перешкоджати взаємодії WebSocket, або тому що вони не налаштовані на передачу заголовка Upgrade, або тому що вони закривають довготривалі з'єднання, які, здається, неактивні. Це означає, що використання WebSocket для внутрішніх програм у межах брандмауера є простішим рішенням, ніж для публічних програм.