Для сервлет-додатків Spring Boot передбачає підтримку вбудованих серверів
Tomcat, Jetty, і Undertow.
Більшість розробників
використовують відповідний "стартер" для отримання повністю налаштованого екземпляра. За замовчуванням вбудований
сервер прослуховує HTTP-запити через порт 8080
.
Сервлети, фільтри та слухачі
При
використанні вбудованого контейнера сервлетів можна зареєструвати сервлети, фільтри та будь-які слухачі (такі як
HttpSessionListener
) зі специфікації сервлетів, або використовуючи біни Spring, або здійснюючи
сканування компонентів сервлетів.
Реєстрація сервлетів, фільтрів та слухачів як бінів Spring
Будь-який екземпляр Servlet
, Filter
або
*Listener
сервлета, який є біном Spring, реєструється у вбудованому контейнері. Це може бути особливо
зручно, якщо потрібно послатися на значення з
application.properties
під час конфігурування.
За замовчуванням, якщо контекст містить лише один
сервлет, він відображається на /
. У разі кількох сервлет-бінів ім'я біна використовується як префікс
шляху. Фільтри відображаються на /*
.
Якщо відображення на основі угод недостатньо гнучке, то
можна використовувати класи ServletRegistrationBean
, FilterRegistrationBean
та ServletListenerRegistrationBean
для повного контролю.
Зазвичай бін-фільтр можна не впорядковувати. Якщо потрібно певне впорядкування,
необхідно анотувати Filter
за допомогою анотації @Order
або реалізувати його як клас
Ordered
. Конфігурувати порядок Filter
, анотувавши його метод біна за допомогою анотації
@Order
, не можна. Якщо не можна змінити клас Filter
, щоб додати анотацію
@Order
або реалізувати клас Ordered
, необхідно визначити
FilterRegistrationBean
для Filter
та встановити порядок реєстраційного біна за допомогою
методу setOrder(int)
. Уникай конфігурування фільтра, який читає тіло запиту Ordered.HIGHEST_PRECEDENCE
,
оскільки це може суперечити конфігурації кодування символів вашої програми. Якщо фільтр сервлета обгортає запит,
його налаштований порядок виконання повинен бути меншим або дорівнювати OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER
.
Filter
у програмі,
активуй логування на рівні налагодження для групи вебжурналювання (logging.level.web=debug
).
Детальна інформація про зареєстровані фільтри, включно з їхнім порядком і шаблонами URL-адрес, буде реєструватися
при
початковому запуску. Будь уважним при реєстрації бінів Filter
, оскільки їхні екземпляри створюються на
дуже ранніх стадіях життєвого циклу програми.
Якщо необхідно зареєструвати Filter
, який взаємодіє з іншими бінами, використовуй замість нього
DelegatingFilterProxyRegistrationBean
.
Ініціалізація контексту сервлетів
Вбудовані контейнери сервлетів не виконують безпосередньо інтерфейс
servlet 3.0+ під назвою javax.servlet.ServletContainerInitializer
або інтерфейс org.springframework.web.WebApplicationInitializer
зі Spring. Це навмисне проєктне рішення, покликане знизити ризик того, що сторонні бібліотеки, розроблені для
виконання всередині war-файлу, можуть зламати програми Spring Boot.
Якщо потрібно виконати ініціалізацію контексту сервлетів у додатку Spring Boot, необхідноо зареєструвати бін, який
реалізує інтерфейс org.springframework.boot.web.servlet.ServletContextInitializer
.
Єдиний метод onStartup
забезпечує доступ до ServletContext
і, в разі необхідності, може
бути
легко використаний як адаптер до існуючого WebApplicationInitializer
.
Сканування на предмет сервлетів, фільтрів та слухачів
При використанні вбудованого контейнера автоматичну реєстрацію класів,
позначених анотаціями @WebServlet
, @WebFilter
та @ WebListener
можна
активувати за допомогою анотації @ServletComponentScan
.
@ServletComponentScan
не працює в автономному контейнері, де
замість неї використовуються вбудовані механізми виявлення контейнера.
The ServletWebServerApplicationContext
З точки зору внутрішнього влаштування Spring Boot використовує
інший тип ApplicationContext
для підтримки вбудованого контейнера сервлетів. ServletWebServerApplicationContext
— це особливий тип WebApplicationContext
, який самозавантажується шляхом пошуку єдиного біна ServletWebServerFactory
.
Зазвичай автоматично конфігуруються TomcatServletWebServerFactory
,
JettyServletWebServerFactory
або UndertowServletWebServerFactory
.
ApplicationContext
та ServletWebServerFactory
створюються без твоєї участі.
У конфігурації вбудованого контейнера ServletContext
встановлюється як елемент запуску сервера,
який відбувається під час ініціалізації контексту програми. У зв'язку з цим біни в ApplicationContext
не можна надійно ініціалізувати за допомогою ServletContext
. Один зі способів обходу цього обмеження —
впровадження ApplicationContext
як залежності від біну та звернення до ServletContext
лише
в разі необхідності. Інший спосіб — використовувати зворотний виклик відразу після запуску сервера. Це можна зробити
за
допомогою ApplicationListener
, який прослуховує ApplicationStartedEvent
таким чином:
Персоналізація налаштувань вбудованих контейнерів сервлетів
Загальні параметри контейнера сервлетів
можна конфігурувати за допомогою властивостей Environment
зі Spring. Зазвичай властивості
визначаються у файлі application.properties
або application.yaml
.
Загальні параметри сервера включають:
Параметри мережі: порт для прослуховування вхідних HTTP-запитів (
server.port
), адреса інтерфейсу для прив'язки доserver.address
, тощо.Параметри сесії: чи зберігається сесія тривало (
server.servlet.session.persistent
), час очікування сесії (server.servlet.session.timeout
), розташування даних сесії (server.servlet.session.store-dir
) та cookie-конфігурація сесії (server.servlet.session.cookie.*
).Керування помилками: розташування сторінки помилок (
server.error.path
) тощо.SSL
HTTP-стискання
Spring Boot вживає всіх необхідних заходів, щоб відкривати доступ до якомога більшої кількості загальних
налаштувань, але це не завжди можливо. У таких випадках спеціалізованими просторами імен передбачені специфічні для
сервера налаштування (див. server.tomcat
та server.undertow
). Наприклад, журнали доступу
можна налаштувати з урахуванням специфічних особливостей вбудованого контейнера сервлетів.
ServerProperties
.
Атрибут SameSite для файлів cookie
Веббраузери можуть використовувати атрибут SameSite
для файлів cookie, щоб керувати тим, чи передаються файли cookie взагалі при міжсайтових запитах і яким чином.
Атрибут особливо актуальний для сучасних веббраузерів, які почали змінювати значення за замовчуванням, яке
використовується за відсутності атрибута.
Якщо ти хочеш змінити атрибут SameSite
твого
сесійного файлу cookie, можеш використовувати властивість server.servlet.session.cookie.same-site
.
Ця властивість підтримується автоматично налаштованими серверами Tomcat, Jetty і Undertow. Він також
використовується для налаштування бінів SessionRepository
на основі сервлетів Сесія в Spring.
Наприклад, якщо потрібно, щоб сесійний файл cookie мав атрибут SameSite
, значення якого одно
None
, то можна додати наступний код до файлу application.properties
або application.yaml
:
server.servlet.session.cookie.same-site=none
server:
servlet:
session:
cookie:
same-site: "none"
Якщо ти хочеш змінити атрибут SameSite
для інших файлів cookie, доданих у HttpServletResponse
,
то можеш використовувати CookieSameSiteSupplier
. CookieSameSiteSupplier
передається
Cookie
і може повернути значення SameSite
або null
.
Існує низка
допоміжних фабричних та фільтраційних методів, які можна використовувати для швидкого пошуку певних файлів cookie.
Наприклад, додавання наступного біна автоматично застосує SameSite
з Lax
для всіх файлів
cookie з ім'ям, що відповідає регулярному виразу myapp.*
.
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MySameSiteConfiguration {
@Bean
public CookieSameSiteSupplier applicationCookieSameSiteSupplier() {
return CookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*");
}
}
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MySameSiteConfiguration {
@Bean
fun applicationCookieSameSiteSupplier(): CookieSameSiteSupplier {
return CookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*")
}
}
Програмна персоналізація налаштувань
Якщо необхідно програмно налаштувати вбудований контейнер сервлетів, то можна зареєструвати бін Spring, який
реалізує інтерфейс WebServerFactoryCustomizer
. WebServerFactoryCustomizer
надає доступ
до фабрики ConfigurableServletWebServerFactory
, яка містить безліч сеттерів. У цьому прикладі
показано програмне налаштування порту:
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;
@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory
import org.springframework.stereotype.Component
@Component
class MyWebServerFactoryCustomizer : WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
override fun customize(server: ConfigurableServletWebServerFactory) {
server.setPort(9000)
}
}
TomcatServletWebServerFactory
, JettyServletWebServerFactory
та UndertowServletWebServerFactory
– це спеціальні варіанти ConfigurableServletWebServerFactory
, які мають додаткові сеттери для
Tomcat, Jetty та Undertow відповідно. У цьому прикладі показано, як налаштувати TomcatServletWebServerFactory
,
який надає доступ до пов'язаних з Tomcat параметрів конфігурації:
import java.time.Duration;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class MyTomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory server) {
server.addConnectorCustomizers((connector) -> connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis()));
}
}>
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component
import java.time.Duration
@Component
class MyTomcatWebServerFactoryCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
override fun customize(server: TomcatServletWebServerFactory) {
server.addConnectorCustomizers({ connector -> connector.asyncTimeout = Duration.ofSeconds(20).toMillis() })
}
}
Пряма персоналізація налаштувань ConfigurableServletWebServerFactory
У більш складних випадках застосування, що вимагають розширення з ServletWebServerFactory
, можна
самостійно відкрити бін такого типу.
Для багатьох параметрів конфігурації передбачені сетери. Також передбачено кілька "перехоплювачів" для захищених методів, якщо потрібно зробити щось неординарніше.
Обмеження JSP
При запуску програми Spring Boot, яка використовує вбудований контейнер сервлетів (і упаковано як виконуваний архів), існують деякі обмеження засобів підтримки JSP.
З Jetty і Tomcat все має працювати, якщо ти використовуєш упаковку до war-файлу. war-файл, що виконується, буде працювати при запуску через
java-jar
, а також буде розгортатися в будь-якому стандартному контейнері. Сторінки JSP не підтримуються під час використання jar-файлу, що виконується.Undertow не підтримує сторінки JSP.
Створення кастомної сторінки
error.jsp
не перевизначає стандартне подання для обробки помилок. Натомість слід використовувати кастомні сторінки помилок.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ