Spring WebFlux framework - WebFlux configuration

Next blog: https://blog.csdn.net/qq_43605444/article/details/122420890?spm=1001.2014.3001.5502

11. WebFlux configuration

The WebFlux Java configuration declares the components required to process requests using annotated controllers or functional endpoints, and provides an API to customize the configuration. This means that you do not need to know the underlying beans created by Java configuration. However, if you want to know about them, you can view them in Web flux configuration support or read more about them in special Bean types.

For more advanced customizations that are not available in the configuration API, you can gain full control of the configuration through the advanced configuration mode.

11.1 enable WebFlux configuration

You can use the @ EnableWebFlux annotation in the Java configuration, as shown in the following example:

@Configuration
@EnableWebFlux
public class WebConfig {
}

The previous example registers many Spring WebFlux infrastructure bean s and adapts to the dependencies available on the classpath - for JSON, XML, and so on.

11.2 WebFlux configuration API

In your Java configuration, you can implement the WebFluxConfigurer interface, as shown in the following example:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    // Implement configuration methods...
}

11.3 Conversion, formatting

By default, formatters of various number and date types are installed, and customization through @ NumberFormat and @ DateTimeFormat on the field is supported.

To register a custom formatter and converter in the Java configuration, use the following command:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // ...
    }

}

By default, Spring WebFlux takes the request locale into account when parsing and formatting date values. This applies to forms where the date is represented as a string with an input form field. However, for the date and time form fields, the browser uses the fixed format defined in the HTML specification. In this case, you can customize the date and time format as follows:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setUseIsoFormat(true);
        registrar.registerFormatters(registry);
    }
}

For more information on when to use FormatterRegistrar implementation, see FormatterRegistrar SPI and FormattingConversionServiceFactoryBean.

11.4 verification

By default, if Bean Validation (for example, Hibernate Validator) exists in the classpath, LocalValidatorFactoryBean will be registered as a global validator for use with @ Valid and @ Validated on the @ Controller method parameters.

In your Java configuration, you can customize the global Validator instance, as shown in the following example:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public Validator getValidator(); {
        // ...
    }

}

Note that you can also register the Validator implementation locally, as shown in the following example:

@Controller
public class MyController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(new FooValidator());
    }

}

If you need to inject LocalValidatorFactoryBean somewhere, create a bean and mark it with @ Primary to avoid conflicts with those declared in the MVC configuration.

11.5 content type analysis

You can configure how Spring WebFlux determines the request media type of the @ Controller instance from the request. By default, only the Accept header is selected, but you can also enable policies based on query parameters.

The following example shows how to customize the content type resolution of a request:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
        // ...
    }
}

11.6 HTTP message codec

The following example shows how to customize how request and response bodies are read and written:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        configurer.defaultCodecs().maxInMemorySize(512 * 1024);
    }
}

The ServerCodecConfigurer provides a default set of readers and writers. You can use it to add more readers and writers, customize the default, or completely replace the default.

For Jackson JSON and XML, consider using Jackson2ObjectMapperBuilder, which uses the following properties to customize Jackson's default properties:

  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES is disabled.
  • MapperFeature.DEFAULT_VIEW_INCLUSION is disabled.

It also automatically registers the following well-known modules if they are detected in the classpath:

  • Jackson datatype joda: joda time type is supported.
  • jackson-datatype-jsr310: supports Java 8 date and time API types.
  • jackson-datatype-jdk8: supports other Java 8 types, such as Optional.
  • Jackson module Kotlin: supports Kotlin classes and data classes.

11.7 view parser

The following example shows how to configure the view parser:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        // ...
    }
}

ViewResolverRegistry has shortcuts to view technology integrated with the Spring framework. The following example uses FreeMarker (you also need to configure the underlying FreeMarker view technology):

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.freeMarker();
    }

    // Configure Freemarker...

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("classpath:/templates");
        return configurer;
    }
}

You can also insert any ViewResolver implementation, as shown in the following example:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        ViewResolver resolver = ... ;
        registry.viewResolver(resolver);
    }
}

To support content negotiation and rendering other formats through view parsing (except HTML), you can configure one or more default views based on the HttpMessageWriterView implementation, which accepts any available codec from spring web. The following example shows how to do this:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.freeMarker();

        Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
        registry.defaultViews(new HttpMessageWriterView(encoder));
    }

    // ...
}

For more information about view technologies integrated with Spring WebFlux, see view technologies.

11.8 static resources

This option provides a convenient way to provide static resources from a list of resource-based locations.

In the next example, given a request starting with / resources, the relative path is used to find and provide static resources relative to / static on the classpath. The service life of resources is one year to ensure maximum use of browser cache and reduce HTTP requests from browsers. The last modified header is also evaluated and, if present, returns a 304 status code. The following list shows examples:

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

}

The resource handler also supports a series of ResourceResolver and ResourceTransformer implementations that can be used to create a tool chain for processing optimized resources.

You can use VersionResourceResolver for versioned resource URL s based on MD5 hash values calculated from content, fixed application versions, or other information. Content version strategy (MD5 hash) is a good choice, with some obvious exceptions (such as JavaScript resources used with module loaders).

The following example shows how to use VersionResourceResolver in a Java configuration:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/public/")
                .resourceChain(true)
                .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
    }

}

You can use the ResourceUrlProvider to rewrite the URL and apply the complete parser and converter chain (for example, insert version). The WebFlux configuration provides a ResourceUrlProvider so that it can be injected into others.

Unlike Spring MVC, there is no way to transparently rewrite the static resource URL in WebFlux, because there is no view technology to take advantage of the non blocking chain of parsers and converters. When only local resources are provided, the solution is to use the ResourceUrlProvider directly (for example, through custom elements) and block it.

Note that when using both encoded resource resolver (for example, Gzip, Brotli encoding) and versioned resource resolver, they must be registered in this order to ensure that content-based versions are always reliably calculated based on uncoded files.

WebJars is also supported through WebJarsResourceResolver, when org WebJars: the WebJars locator core library is automatically registered when it appears on the classpath. The parser can rewrite the URL to include the version of the jar, or it can match an incoming URL without a version - for example, from / jQuery / jQuery. Com Min.js to / jQuery / 1.2.0 / jQuery min.js.

The Java configuration based on ResourceHandlerRegistry provides more options for fine-grained control, such as the last modified behavior and optimized resource parsing.

11.9 path matching

You can customize options related to path matching. For details on the options, see the pathmatchconfigurator Javadoc. The following example shows how to use the pathmatchconfigurator:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer
            .setUseCaseSensitiveMatch(true)
            .setUseTrailingSlashMatch(false)
            .addPathPrefix("/api",
                    HandlerTypePredicate.forAnnotation(RestController.class));
    }
}

Spring WebFlux relies on the analytical representation of the request path, called RequestPath, to access the decoded path segment value and delete the semicolon content (i.e. path or matrix variables). This means that, unlike Spring MVC, you do not need to indicate whether to decode the request path or whether to delete the semicolon content for path matching.

Spring WebFlux also does not support suffix pattern matching, which is different from Spring MVC. We also suggest to get rid of dependence on it.

11.10 WebSocketService

The WebFlux Java configuration declares a WebSocketHandlerAdapter bean that supports calls to WebSocket handlers. This means that in order to handle the WebSocket handshake request, all that is left is to map the WebSocketHandler to the URL through simpleurhandlermapping.

In some cases, you may need to create a WebSocketHandlerAdapter bean using the provided WebSocketService service, which allows you to configure WebSocket server properties. For example:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public WebSocketService getWebSocketService() {
        TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
        strategy.setMaxSessionIdleTimeout(0L);
        return new HandshakeWebSocketService(strategy);
    }
}

11.11 advanced configuration mode

@EnableWebFlux import DelegatingWebFluxConfiguration:

  • Provides a default Spring configuration for WebFlux applications
  • Detect and delegate to the WebFluxConfigurer implementation to customize the configuration.

For advanced mode, you can delete @ EnableWebFlux and extend it directly from DelegatingWebFluxConfiguration instead of implementing WebFluxConfigurer, as shown in the following example:

@Configuration
public class WebConfig extends DelegatingWebFluxConfiguration {

    // ...
}

You can keep existing methods in Web Config, but you can now override the bean declaration in the base class, and there are still any number of other WebMvcConfigurer implementations on the classpath.

Article translation reference: https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux

Keywords: Java Maven Spring WebFlux Back-end

Added by riginosz on Mon, 10 Jan 2022 17:43:42 +0200