Spring Webflux, как раздавать статический контент?

Spring Webflux, фреймворк для разработки реактивных приложений, предоставляет несколько способов для раздачи статического контента.

Первый способ - использование класса ResourceWebHandler, который является обработчиком статического контента. Для его использования необходимо создать экземпляр класса ResourceWebHandler и указать путь к статическим ресурсам:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
   @Bean
   public ResourceWebHandler resourceWebHandler() {
       return new ResourceWebHandler();
   }

   @Override
   public void addResourceHandlers(ResourceHandlerRegistry registry) {
       registry.addResourceHandler("/static/**")
               .resourceChain(false)
               .addResolver(new PathResourceResolver() {
                   @Override
                   protected Resource getResource(String resourcePath, Resource location) throws IOException {
                       Resource requestedResource = location.createRelative(resourcePath);

                       return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                               : new ClassPathResource("/static/index.html");
                   }
               });
   }

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

   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
       registry.addViewController("/").setViewName("forward:/static/index.html");
   }

   @Bean
   public RouterFunction<ServerResponse> indexRouter(@Value("classpath:/static/index.html") final Resource indexHtml) {
       return route(GET("/static/index.html"), request -> ok().bodyValue(indexHtml));
   }

   @Override
   public void configurePathMatching(PathMatchConfigurer configurer) {
       configurer.setUseSuffixPatternMatch(false);
   }
}

В приведенном примере, приложение раздаст статический контент, расположенный в папке /static в класспасе. Если запрашиваемый ресурс не найден, будут возвращены данные из файла index.html.

Второй способ - использование класса WebFluxConfigurerComposite. Этот класс позволяет настроить статическую обработку ресурсов с использованием ResourceWebHandler, а также настроить другие параметры:

@Configuration
public class WebConfig implements WebFluxConfigurer {
   @Override
   public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
       configurer
               .defaultCodecs()
               .maxInMemorySize(16 * 1024 * 1024);
   }

   @Override
   public void configurePathMatching(PathMatchConfigurer configurer) {
       configurer.setUseSuffixPatternMatch(false);
   }

   @Override
   public void addResourceHandlers(ResourceHandlerRegistry registry) {
       registry.addResourceHandler("/static/**")
               .resourceChain(false)
               .addResolver(new PathResourceResolver() {
                   @Override
                   protected Resource getResource(String resourcePath, Resource location) throws IOException {
                       Resource requestedResource = location.createRelative(resourcePath);

                       return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                               : new ClassPathResource("/static/index.html");
                   }
               });
   }

   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
       registry.addViewController("/").setViewName("forward:/static/index.html");
   }

   @Bean
   public RouterFunction<ServerResponse> indexRouter(@Value("classpath:/static/index.html") final Resource indexHtml) {
       return route(GET("/static/index.html"), request -> ok().bodyValue(indexHtml));
   }
}

В данном примере, настройка статической обработки ресурсов выполняется с использованием метода addResourceHandlers() класса ResourceHandlerRegistry, который добавляет обработчик ResourceWebHandler.

Третий способ - использование класса RouterFunction, который определяет пути для раздачи статических ресурсов:

@Configuration
public class WebConfig {
   @Bean
   public RouterFunction<ServerResponse> staticResourceRouter() {
       return RouterFunctions.resources("/static/**", new ClassPathResource("static/"));
   }
}

В данном примере, статические ресурсы будут раздаваться по пути /static/** из класспаса.

В результате, при использовании любого из указанных выше способов, вы сможете раздавать статический контент в Spring Webflux.