java Spring Webflux,如何转发到index.html以提供静态内容

5tmbdcev  于 2023-06-28  发布在  Java
关注(0)|答案(5)|浏览(115)

spring-boot-starter-webflux(Sping Boot v2.0.0.M2)已经像spring-boot-starter-web一样配置为在资源中的静态文件夹中提供静态内容。但它不会转发到index.html。在Spring MVC中,可以这样配置:

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

如何在Spring Webflux中实现?

pod7payv

pod7payv1#

使用WebFilter:

@Component
public class CustomWebFilter implements WebFilter {
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    if (exchange.getRequest().getURI().getPath().equals("/")) {
        return chain.filter(exchange.mutate().request(exchange.getRequest().mutate().path("/index.html").build()).build());
    }

    return chain.filter(exchange);
  }
}
wpcxdonn

wpcxdonn2#

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;

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

kyks70gy4#

使用WebFluxKotlinDSL:

@Bean
open fun indexRouter(): RouterFunction<ServerResponse> {
    val redirectToIndex =
            ServerResponse
                    .temporaryRedirect(URI("/index.html"))
                    .build()

    return router {
        GET("/") {
            redirectToIndex // also you can create request here
        }
    }
}
voj3qocg

voj3qocg5#

如果您像我一样来这里寻找一个适用于动态路由的解决方案,作为SPA用例的后备解决方案,则有一个开放的 Spring 问题here
下面的WebExceptionHandler为我解决了这个问题

@Component
@Order(-2)
public class HtmlRequestNotFoundHandler implements WebExceptionHandler {

    private final DispatcherHandler dispatcherHandler;

    private final RequestPredicate PREDICATE = RequestPredicates.accept(MediaType.TEXT_HTML);

    public HtmlRequestNotFoundHandler(DispatcherHandler dispatcherHandler) {
        this.dispatcherHandler = dispatcherHandler;
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
        if (
            isNotFoundAndShouldBeForwarded(exchange, throwable)
        ) {
            var forwardRequest = exchange.mutate().request(it -> it.path("/index.html"));
            return dispatcherHandler.handle(forwardRequest.build());
        }
        return Mono.error(throwable);
    }

    private boolean isNotFoundAndShouldBeForwarded(ServerWebExchange exchange, Throwable throwable) {
        if (throwable instanceof ResponseStatusException
            && ((ResponseStatusException) throwable).getStatusCode() == HttpStatus.NOT_FOUND
        ) {

            var serverRequest = ServerRequest.create(exchange, Collections.emptyList());
            return PREDICATE.test(serverRequest);
        }

        return false;
    }

}

相关问题