Я хотел бы использовать RouteFunction
вместо @RestController, когда Spring 5 стабилен. Определите HandlerFunction для обработки запроса, а затем объявите RouteFunction
для сопоставления запроса с HandlerFunction:
public Mono<ServerResponse> get(ServerRequest req) {
return this.posts
.findById(req.pathVariable("id"))
.flatMap((post) -> ServerResponse.ok().body(Mono.just(post), Post.class))
.switchIfEmpty(ServerResponse.notFound().build());
}
См. Полные примеры кодов здесь.
Версия Kotlin, определите функцию для обработки запроса, используйте RouteFunctionDSL
для сопоставления входящего запроса с HandlerFuncation:
fun get(req: ServerRequest): Mono<ServerResponse> {
return this.posts.findById(req.pathVariable("id"))
.flatMap { post -> ok().body(Mono.just(post), Post::class.java) }
.switchIfEmpty(notFound().build())
}
Это может быть выражение, например:
fun get(req: ServerRequest): Mono<ServerResponse> = this.posts.findById(req.pathVariable("id"))
.flatMap { post -> ok().body(Mono.just(post), Post::class.java) }
.switchIfEmpty(notFound().build())
Полные примеры кодов Kotlin DSL можно найти здесь.
Если вы предпочитаете традиционные контроллеры для предоставления REST API, попробуйте этот подход.
Сначала определите исключение, например. PostNotFoundException
. Потом закидывай в контроллер.
@GetMapping(value = "/{id}")
public Mono<Post> get(@PathVariable(value = "id") Long id) {
return this.posts.findById(id).switchIfEmpty(Mono.error(new PostNotFoundException(id)));
}
Определите ExceptionHandler
для обработки исключения и зарегистрируйте его в HttpHandler
.
@Profile("default")
@Bean
public NettyContext nettyContext(ApplicationContext context) {
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context)
.exceptionHandler(exceptionHandler())
.build();
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
HttpServer httpServer = HttpServer.create("localhost", this.port);
return httpServer.newHandler(adapter).block();
}
@Bean
public WebExceptionHandler exceptionHandler() {
return (ServerWebExchange exchange, Throwable ex) -> {
if (ex instanceof PostNotFoundException) {
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
return Mono.error(ex);
};
}
Ознакомьтесь с полными кодами здесь. Пользователи Spring Boot могут ознакомиться с этим примером .
Обновление : В последней весне 5.2 я обнаружил, что в целом @RestControllerAdvice
работает с контроллерами в приложениях webflux.
person
Hantsy
schedule
19.08.2017