CodeGym /Cursos Java /Módulo 5. Spring /Configuración de WebFlux

Configuración de WebFlux

Módulo 5. Spring
Nivel 14 , Lección 1
Disponible

El La configuración de WebFlux Java declara los componentes necesarios para procesar solicitudes utilizando controladores anotados o puntos finales funcionales y proporciona una API para configurar la configuración. Esto significa que no necesita comprender los beans subyacentes creados por la configuración de Java.

Si necesita configuraciones avanzadas que no están disponibles en la API de configuración, puede obtener control total sobre la configuración usando la configuración avanzada. modo de configuración.

Habilitación de la configuración de WebFlux

Puede utilizar la anotación @EnableWebFlux en una configuración de Java como se muestra en el siguiente ejemplo:

Java

@Configuration
@EnableWebFlux
public class WebConfig {
}
Kotlin

@Configuration
@EnableWebFlux
class WebConfig

En el ejemplo anterior, se registran varios beans de infraestructura Spring WebFlux y adaptado a las dependencias disponibles en el classpath - para JSON, XML y otros formatos.

API de configuración WebFlux

En su configuración de Java, puede implementar el WebFluxConfigurer interfaz, como se muestra en el siguiente ejemplo:

Java

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
// Implementar métodos de configuración...
}
Kotlin

@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
// Implementar métodos de configuración...
}

Conversión, formato

De forma predeterminada, se instalan formateadores para varios tipos de números y fechas, junto con herramientas para admitir la personalización mediante @NumberFormat y @DateTimeFormat para los campos.

Para registrar formateadores y convertidores personalizados en la configuración de Java, utilice lo siguiente:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// ...
}
} 
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
// ...
}
}

De forma predeterminada, Spring WebFlux tiene en cuenta la configuración regional de la solicitud al analizar y formatear los valores de fecha. Esto es cierto para formularios donde las fechas se representan como cadenas con campos de formulario de "entrada". Sin embargo, para los campos de formulario "fecha" y "hora", los navegadores utilizan un formato fijo definido en la especificación HTML. Para tales casos, el formato de fecha y hora se puede configurar de la siguiente manera:

Java

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
val registrar = DateTimeFormatterRegistrar()
registrar.setUseIsoFormat(true)
registrar.registerFormatters(registry)
}
}

Validación

Valor predeterminado si hay un Bean en el classpath La validación está presente (por ejemplo, Hibernate Validator), un LocalValidatorFactoryBean está registrado como un validador global para su uso con la anotación @Valid y la propiedad Validated en argumentos del método.

En la configuración de Java, puede configurar una instancia global de Validator, como se muestra en el siguiente ejemplo:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public Validator getValidator() {
// ...
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun getValidator(): Validator {
// ...
}
}

Tenga en cuenta que también es posible registrar implementaciones de Validator localmente, como se muestra en el siguiente ejemplo:

Java
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}
Kotlin
@Controller
class MyController {
@InitBinder
protected fun initBinder(binder: WebDataBinder) {
binder.addValidators(FooValidator())
}
}
Si es necesario que LocalValidatorFactoryBean se inyectó en algún lugar, cree un bean y márquelo con la anotación @Primary para evitar conflictos con lo que se declaró en la configuración de MVC.

Resolutores de tipos de contenido

Puede configurar cómo Spring WebFlux determina los tipos de medios solicitados para instancias @Controller a partir de una solicitud. De forma predeterminada, solo se marca el encabezado Aceptar, pero también puede habilitar una estrategia basada en los parámetros de la solicitud.

El siguiente ejemplo muestra cómo configurar el permiso del tipo de contenido solicitado. :

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
// ...
}
} 
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureContentTypeResolver(builder: RequestedContentTypeResolverBuilder) {
// ...
}
}

Códecs de mensajes HTTP

El siguiente ejemplo muestra cómo configurar la lectura y escritura del cuerpo de solicitud y respuesta:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(512 * 1024);
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
// ...
}
}

ServerCodecConfigurer proporciona un conjunto predeterminado de lectores y escritores. Puede usarlo para agregar lectores y escritores adicionales, personalizar los predeterminados o reemplazar los predeterminados por completo.

Para Jackson JSON y XML, considere usar Jackson2ObjectMapperBuilder , que configura las propiedades de la biblioteca Jackson de forma predeterminada de la siguiente manera:

Los siguientes módulos conocidos también se registran automáticamente si se encuentran en el classpath:

Reconocedores de vistas

El siguiente ejemplo muestra cómo configurar el reconocimiento de vistas:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// ...
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
// ...
}
}}

ViewResolverRegistry contiene abreviaturas de las tecnologías de presentación con las que se integra Spring Framework. El siguiente ejemplo utiliza FreeMarker (que también requiere la personalización de la tecnología de presentación subyacente de FreeMarker):

Java

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker();
}
// Configurar FreeMarker...
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("classpath:/templates");
return configurer;
}
}
Kotlin

@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
}
// Configurar FreeMarker...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("classpath:/templates")
}
}

También puede conectar cualquier implementación de ViewResolver, como se muestra en el siguiente ejemplo:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ViewResolver resolver = ... ;
registry.viewResolver(resolver);
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
val resolver: ViewResolver = ...
registry.viewResolver(resolver
}
}

Para brindar soporte para la negociación de contenido y la representación de otros formatos a través de la resolución de vista (que no sean HTML), puede configurar una o más vistas predeterminadas basadas en el implementación HttpMessageWriterView, que acepta cualquiera de los códecs disponibles de spring-web. El siguiente ejemplo muestra cómo hacer esto:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker();
Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
registry.defaultViews(new HttpMessageWriterView(encoder));
}
// ...
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
val encoder = Jackson2JsonEncoder()
registry.defaultViews(HttpMessageWriterView(encoder))
}
// ...
}

Recursos estáticos

Esta opción proporciona una manera conveniente de manejar recursos estáticos desde una lista de ubicaciones basadas en Recurso.

En el siguiente ejemplo, si la solicitud comienza con /resources, la ruta relativa se utiliza para buscar y procesar recursos estáticos relativos a /static en el classpath. Los recursos se procesan con una fecha de vencimiento de un año para garantizar el uso máximo de la caché del navegador y reducir la cantidad de solicitudes HTTP realizadas por el navegador. El encabezado Last-Modified también se evalúa y, si está presente, se devuelve un código de estado 304. El siguiente listado muestra un ejemplo:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
        .addResourceLocations("/public", "classpath:/static/")
        .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
registry.addResourceHandler("/resources/**")
        .addResourceLocations("/public", "classpath:/static/")
        .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
}
}

El controlador de recursos también admite el encadenamiento de implementaciones ResourceResolver e implementaciones ResourceTransformer, que se puede utilizar para crear un conjunto de herramientas para trabajar con recursos optimizados.

Puedes utilizar VersionResourceResolver para URL de recursos versionados basados en un hash MD5 derivado del contenido, la versión inmutable de la aplicación u otra información. ContentVersionStrategy (hash MD5) es una elección bien pensada, pero con algunas excepciones notables (como los recursos de JavaScript utilizados con el cargador de módulos).

El siguiente ejemplo muestra cómo utilizar VersionResourceResolver en la configuración de Java:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
        .addResourceLocations("/public/")
        .resourceChain(true)
        .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
registry.addResourceHandler("/resources/**")
        .addResourceLocations("/public/")
        .resourceChain(true)
        .addResolver(VersionResourceResolver().addContentVersionStrategy("/**"))
}
}

Puedes usar ResourceUrlProvider para reescribir las URL y aplicar la cadena completa de resolutores y solucionadores (por ejemplo, para insertar versiones). La configuración de WebFlux proporciona un ResourceUrlProvider que se puede inyectar en otros beans.

A diferencia de Spring MVC, WebFlux actualmente no tiene la capacidad de reescribir de forma transparente las URL de recursos estáticos porque no existen tecnologías de presentación. Que podría utilizar una cadena sin bloqueo de resolutores y resolutores. Al procesar solo recursos locales, una solución alternativa es usar ResourceUrlProvider directamente (por ejemplo, a través de un elemento personalizado) y bloquear.

Tenga en cuenta que cuando se usa como EncodedResourceResolver (por ejemplo, Gzip, Brotli) y VersionedResourceResolver, deben registrarse en un orden que calcule de manera confiable las versiones basadas en el contenido del archivo sin codificar.

WebJars también se admiten mediante WebJarsResourceResolver, que se registra automáticamente cuando la biblioteca está presente org.webjars:webjars-locator-core en classpath. El solucionador puede reescribir las URL para incluir la versión jar, así como hacer coincidir las URL entrantes sin versiones, por ejemplo, desde /jquery/jquery.min.js hasta /jquery/1.2.0/jquery.min.js.

La configuración de Java basada en ResourceHandlerRegistry proporciona capacidades adicionales para un control detallado, como la lógica de último cambio y la resolución optimizada de recursos.

Asignación de rutas

Puede configurar ajustes relacionados con la asignación de rutas. Para obtener más información sobre parámetros individuales, consulte el javadoc en PathMatchConfigurer. El siguiente ejemplo muestra cómo utilizar PathMatchConfigurer:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer
    .setUseCaseSensitiveMatch(true)
    .setUseTrailingSlashMatch(false)
    .addPathPrefix("/api",
            HandlerTypePredicate.forAnnotation(RestController.class));
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
@Override
fun configurePathMatch(configurer: PathMatchConfigurer) {
configurer
    .setUseCaseSensitiveMatch(true)
    .setUseTrailingSlashMatch(false)
    .addPathPrefix("/api",
            HandlerTypePredicate.forAnnotation(RestController::class.java))
}
}

Spring WebFlux utiliza un análisis representación de ruta una solicitud llamada RequestPath para acceder a los valores decodificados de los segmentos de ruta, con el contenido delimitado por punto y coma eliminado (es decir, variables de ruta o variables de matriz). Esto significa que, a diferencia de Spring MVC, no es necesario especificar si se decodifica la ruta de solicitud o se elimina el contenido separado por punto y coma para que coincida con las rutas.

Spring WebFlux tampoco admite la coincidencia de patrones de sufijos, a diferencia de Spring MVC , donde también recomendamos no usarlo.

WebSocketService

En la configuración de WebFlux Java, el bean WebSocketHandlerAdapter es declarado, que proporciona soporte para llamar a los controladores WebSocket. Esto significa que todo lo que queda para manejar una solicitud de protocolo de enlace de WebSocket es asignar el WebSocketHandler a una URL a través de SimpleUrlHandlerMapping.

En algunos casos, Es posible que necesite crear un bean WebSocketHandlerAdapter con el servicio WebSocketService proporcionado, que le permite configurar las propiedades del servidor que trabaja con el protocolo WebSocket. Por ejemplo:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public WebSocketService getWebSocketService() {
TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
strategy.setMaxSessionIdleTimeout(0L);
return new HandshakeWebSocketService(strategy);
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
@Override
fun webSocketService(): WebSocketService {
val strategy = TomcatRequestUpgradeStrategy().apply {
    setMaxSessionIdleTimeout(0L)
}
return HandshakeWebSocketService(strategy)
}
}

Modo de configuración avanzada

@EnableWebFlux importa DelegatingWebFluxConfiguration, que:

  • Pasa la configuración Spring predeterminada para aplicaciones WebFlux

  • descubre y delega autoridad a la implementación WebFluxConfigurer para configurar esta configuración.

En modo avanzado, puede eliminar el @EnableWebFlux código de anotación> y extenderlo directamente desde DelegatingWebFluxConfiguration en lugar de implementar WebFluxConfigurer como se muestra en el siguiente ejemplo:

Java
@Configuration
public class WebConfig extends DelegatingWebFluxConfiguration {
// ...
}
Kotlin
@Configuration
class WebConfig : DelegatingWebFluxConfiguration {
// ...
}

Es posible guardar métodos existentes en WebConfig, pero ahora también será posible anular las declaraciones de beans de la clase base y aún poder tener cualquier cantidad de otras implementaciones de WebMvcConfigurer en el classpath.

HTTP/2

HTTP/2 es compatible con Reactor Netty, Tomcat, Jetty y Undertow. Sin embargo, existen algunas advertencias asociadas con la configuración del servidor. Puede encontrar más información en página wiki a través de HTTP/2.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION