Spring Boot чудово підходить для розробки вебдодатків. Ти можеш створити автономний HTTP-сервер за допомогою
вбудованого Tomcat, Jetty, Undertow або Netty. Більшість вебдодатків використовують модуль spring-boot-starter-web
для швидкого виконання. Ти також можеш компілювати реактивні вебдодатки за допомогою модуля spring-boot-starter-webflux
.
Якщо ти хочеш створювати вебдодатки на основі сервлетів, то можеш скористатися можливостями автоконфігурації Spring Boot для Spring MVC або Jersey.
Фреймворк Spring Web MVC
Фреймворк Spring Web MVC (часто
згадується як Spring MVC) — це повноцінний вебфреймворк за схемою "модель-подання-контролер". Spring MVC дозволяє
створювати спеціальні біни з анотаціями @Controller
або @RestController
для обробки
вхідних HTTP-запитів. Методи в контролері відображаються на протокол HTTP за допомогою анотацій @RequestMapping
.
У наступному коді показано типову анотацію @RestController
, яка працює з даними у форматі JSON:
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users")
public class MyRestController {
private final UserRepository userRepository;
private final CustomerRepository customerRepository;
public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
this.userRepository = userRepository;
this.customerRepository = customerRepository;
}
@GetMapping("/{userId}")
public User getUser(@PathVariable Long userId) {
return this.userRepository.findById(userId).get();
}
@GetMapping("/{userId}/customers")
public List<Customer> getUserCustomers(@PathVariable Long userId) {
return this.userRepository.findById(userId).map(this.customerRepository::findByUser).get();
}
@DeleteMapping("/{userId}")
public void deleteUser(@PathVariable Long userId) {
this.userRepository.deleteById(userId);
}
}
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/users")
class MyRestController(private val userRepository: UserRepository, private val customerRepository: CustomerRepository) {
@GetMapping("/{userId}")
fun getUser(@PathVariable userId: Long): User {
return userRepository.findById(userId).get()
}
@GetMapping("/{userId}/customers")
fun getUserCustomers(@PathVariable userId: Long): ListCustomer> {
return userRepository.findById(userId).map(customerRepository::findByUser).get()
}
@DeleteMapping("/{userId}")
fun deleteUser(@PathVariable userId: Long) {
userRepository.deleteById(userId)
}
}
"WebMvc.fn", функціональний варіант, відокремлює конфігурацію маршрутизації від фактичної обробки запитів, як показано в наступному прикладі:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.function.RequestPredicate;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;
import static org.springframework.web.servlet.function.RequestPredicates.accept;
import static org.springframework.web.servlet.function.RouterFunctions.route;
@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {
private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);
@Bean
public RouterFunction<ServerResponse> routerFunction(MyUserHandler userHandler) {
return route()
.GET("/{user}", ACCEPT_JSON, userHandler::getUser)
.GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
.DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
.build();
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.web.servlet.function.RequestPredicates.accept
import org.springframework.web.servlet.function.RouterFunction
import org.springframework.web.servlet.function.RouterFunctions
import org.springframework.web.servlet.function.ServerResponse
@Configuration(proxyBeanMethods = false)
class MyRoutingConfiguration {
@Bean
fun routerFunction(userHandler: MyUserHandler): RouterFunction<ServerResponse> {
return RouterFunctions.route()
.GET("/{user}", ACCEPT_JSON, userHandler::getUser)
.GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
.DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
.build()
}
companion object {
private val ACCEPT_JSON = accept(MediaType.APPLICATION_JSON)
}
}
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;
@Component
public class MyUserHandler {
public ServerResponse getUser(ServerRequest request) {
...
return ServerResponse.ok().build();
}
public ServerResponse getUserCustomers(ServerRequest request) {
...
return ServerResponse.ok().build();
}
public ServerResponse deleteUser(ServerRequest request) {
...
return ServerResponse.ok().build();
}
}
import org.springframework.stereotype.Component
import org.springframework.web.servlet.function.ServerRequest
import org.springframework.web.servlet.function.ServerResponse
@Component
class MyUserHandler {
fun getUser(request: ServerRequest?): ServerResponse {
return ServerResponse.ok().build()
}
fun getUserCustomers(request: ServerRequest?): ServerResponse {
return ServerResponse.ok().build()
}
fun deleteUser(request: ServerRequest?): ServerResponse {
return ServerResponse.ok().build()
}
}
RouterFunction
, скільки забажаєш. Біни можна впорядкувати, якщо потрібно застосовувати черговість
виконання.
Автоконфігурація Spring MVC
Spring Boot передбачає автоконфігурацію для Spring MVC, яка відмінно працює з більшістю додатків.
Автоконфігурація додає наступні функції до налаштувань Spring за замовчуванням:
Додати біни
ContentNegotiatingViewResolver
іBeanNameViewResolver
.Підтримка обробки статичних ресурсів, включно з підтримкою WebJars.
Автоматична реєстрація бінів
Converter
,GenericConverter
таFormatter
.Підтримка
HttpMessageConverters
.Автоматична реєстрація
MessageCodesResolver
.Підтримка статичного
index.html
.Автоматичне використання біна
ConfigurableWebBindingInitializer
.
Якщо необхідно зберегти ці налаштування Spring Boot MVC і внести додаткові налаштування MVC (перехоплювачі,
форматувальники, контролери представлення та інші функції), то можна додати власний клас, позначений
анотацією @Configuration
, типу WebMvcConfigurer
, але без анотації
@EnableWebMvc
.
Якщо необхідно передати кастомні екземпляри
RequestMappingHandlerMapping
, RequestMappingHandlerAdapter
або ExceptionHandlerExceptionResolver
і водночас зберегти налаштування Spring Boot MVC, то можна оголосити бін типу WebMvcRegistrations
і
використовувати його для передачі кастомних екземплярів цих компонентів.
Якщо необхідно повністю контролювати
роботу Spring MVC, можна додати власну @Configuration
, позначену анотацією
@EnableWebMvc
, або ж додати свій власний клас DelegatingWebMvcConfiguration
, позначений
анотацією @Configuration
, як описано в Javadoc для анотації @ EnableWebMvc
.
Spring MVC використовує ConversionService
, відмінний від
того, який використовується для перетворення значень з файлу application.properties
або application.yaml
.
Це означає, що перетворювачі Period
, Duration
та DataSize
будуть недоступні і
що анотації @DurationUnit
та @ DataSizeUnit
буде проігноровано.
Якщо необхідно персоналізувати налаштування служби ConversionService
, що використовується Spring
MVC, то можна передбачити бін WebMvcConfigurer
з методом addFormatters
. З цього
методу можна реєструвати будь-який перетворювач або делегувати повноваження статичним методам, доступним для
ApplicationConversionService
.
HttpMessageConverters
Spring MVC використовує
інтерфейс HttpMessageConverter
для перетворення HTTP-запитів та відповідей. Адекватні параметри за
замовчуванням передбачені "з коробки". Наприклад, об'єкти можуть бути автоматично перетворені в JSON (за допомогою
бібліотеки Jackson) або в XML (за допомогою розширення Jackson XML, якщо воно доступне, або за допомогою JAXB, якщо
розширення Jackson XML недоступне). За замовчуванням рядки кодуються в UTF-8
.
Якщо необхідно
додати або налаштувати перетворювачі, можна використовувати клас HttpMessageConverters
для Spring Boot,
як показано в наступному лістингу:
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
@Configuration(proxyBeanMethods = false)
public class MyHttpMessageConvertersConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = new AdditionalHttpMessageConverter();
HttpMessageConverter<?> another = new AnotherHttpMessageConverter();
return new HttpMessageConverters(additional, another);
}
}
import org.springframework.boot.autoconfigure.http.HttpMessageConverters
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.HttpMessageConverter
@Configuration(proxyBeanMethods = false)
class MyHttpMessageConvertersConfiguration {
@Bean
fun customConverters(): HttpMessageConverters {
val additional: HttpMessageConverter<*> = AdditionalHttpMessageConverter()
val another: HttpMessageConverter<*> = AnotherHttpMessageConverter()
return HttpMessageConverters(additional, another)
}
}
Будь-який бін HttpMessageConverter
, присутній у контексті, додається до списку перетворювачів.
Так само можна перевизначати перетворювачі за замовчуванням.
MessageCodesResolver
Spring MVC містить
стратегію генерації кодів помилок для виведення повідомлень про помилки прив'язки: MessageCodesResolver
.Якщо
встановлено властивість spring.mvc.message-codes-resolver-format
PREFIX_ERROR_CODE
або
POSTFIX_ERROR_CODE
, Spring Boot створить його для тебе.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ