Spring Boot es ideal para desarrollar aplicaciones web. Puede crear un servidor HTTP independiente utilizando Tomcat, Jetty, Undertow o Netty integrados. La mayoría de las aplicaciones web utilizan el módulo spring-boot-starter-web para una ejecución rápida. También puede compilar aplicaciones web reactivas utilizando el módulo spring-boot-starter-webflux.

Si desea crear aplicaciones web basadas en servlets, puede aprovechar la configuración automática de Spring. Сapacidades Boot para Spring MVC o Jersey.

Spring Web MVC Framework

Spring Web MVC (a menudo denominado "Spring MVC") es un framework web completo basado en el modelo -controlador de vista". Spring MVC le permite crear beans personalizados con anotaciones @Controller o @RestController para manejar las solicitudes HTTP entrantes. Los métodos en el controlador se asignan al protocolo HTTP mediante anotaciones @RequestMapping.

El siguiente código muestra una anotación @RestController típica que funciona con datos JSON:

Java

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);
    }
}
Kotlin

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", una opción funcional, separa la configuración de enrutamiento del procesamiento real de solicitudes, como se muestra en el siguiente ejemplo:

Java

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();
    }
}
Kotlin

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)
    }
}
Java
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();
    }
}
Kotlin

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()
    }
}
Para modular la definición de un enrutador, puede definir tantos beans RouterFunction como desee. Los beans se pueden ordenar si desea aplicar el orden de ejecución.

Configuración automática de Spring MVC

Spring Boot proporciona configuración automática para Spring MVC, que funciona bien con la mayoría de las aplicaciones.

La configuración automática agrega la siguiente funcionalidad además de la configuración predeterminada de Spring:

  • Agregar ContentNegotiatingViewResolver y BeanNameViewResolver beans.

  • Soporte para el procesamiento de recursos estáticos, incluido el soporte para WebJars.

  • Registro automático de Convertidor, GenericConverter beans y Formatter.

  • Soporte para HttpMessageConverters.

  • Registro automático MessageCodesResolver.

  • Soporte para index.html estático.

  • Uso automático del bean ConfigurableWebBindingInitializer.

Si necesita guardar estas configuraciones de Spring Boot MVC y agregue configuraciones MVC adicionales (interceptores, formateadores, controladores de vista y otras funciones), luego puede agregar su propia clase marcada con la anotación @Configuration, como WebMvcConfigurer, pero sin la anotación @EnableWebMvc.

Si necesita pasar instancias personalizadas de RequestMappingHandlerMapping, RequestMappingHandlerAdapter o ExceptionHandlerExceptionResolver y al mismo tiempo preservar la configuración de Spring Boot MVC, luego puede declarar un bean de tipo WebMvcRegistrations y usarlo para pasar instancias personalizadas de estos componentes.

Si necesita controlar completamente el funcionamiento de Spring MVC, puede agregar su propio @Configuration, marcado con @EnableWebMvc. anotación, o puede agregar su propia clase DelegatingWebMvcConfiguration, marcada con la anotación @Configuration, como se describe en el Javadoc para la anotación @ EnableWebMvc.

Spring MVC usa un ConversionService diferente al usado para la conversión de valores desde su aplicación Period o el archivo application.yaml. Esto significa que los convertidores Period, Duration y DataSize no estarán disponibles y que los convertidores @DurationUnit y anotaciones @DataSizeUnit serán ignoradas.

Si necesita personalizar la configuración del servicio ConversionService utilizado por Spring MVC, puede proporcionar un WebMvcConfigurer bean con un método addFormatters. Desde este método, puede registrar cualquier convertidor preferido o delegar autoridad a métodos estáticos disponibles para ApplicationConversionService.

HttpMessageConverters

Spring MVC usa el Interfaz HttpMessageConverter para convertir solicitudes y respuestas HTTP. Se proporcionan configuraciones predeterminadas adecuadas listas para usar. Por ejemplo, los objetos se pueden convertir automáticamente a JSON (usando la biblioteca Jackson) o a XML (usando la extensión Jackson XML si está disponible, o usando JAXB si la extensión Jackson XML no está disponible). De forma predeterminada, las cadenas están codificadas en UTF-8.

Si necesita agregar o personalizar convertidores, puede usar la clase HttpMessageConverters para Spring Boot, como se muestra en el siguiente listado:

Java

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);
    }
}
Kotlin

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)
    }
}

Cualquier bean HttpMessageConverter presente en el contexto , se agrega a la lista de convertidores. Puede anular los solucionadores predeterminados de la misma manera.

MessageCodesResolver

Spring MVC contiene una estrategia de generación de código de error para imprimir mensajes de error vinculantes: MessageCodesResolver. La propiedad está establecida spring.mvc.message-codes-resolver-format PREFIX_ERROR_CODE o POSTFIX_ERROR_CODE, Spring Boot la creará por usted.