public interface PersonRepository {
Mono<Person> getPerson(int id);
Flux<Person> allPeople();
Mono<Void> savePerson(Mono<Person> person);
}
RouterFunction<?> route = route(GET("/person/{id}"), request -> {
Mono<Person> person = Mono.justOrEmpty(request.pathVariable("id"))
.map(Integer::valueOf)
.then(repository::getPerson);
return Response.ok().body(fromPublisher(person, Person.class));
}).and(route(GET("/person"), request -> {
Flux<Person> people = repository.allPeople();
return Response.ok().body(fromPublisher(people, Person.class));
})).and(route(POST("/person"), request -> {
Mono<Person> person = request.body(toMono(Person.class));
return Response.ok().build(repository.savePerson(person));
}));
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);
HttpServer server = HttpServer.create("localhost", 8080);
server.startAndAwait(adapter);
$ curl 'https://localhost:8080/person/1'
{"name":"John Doe","age":42}
類型:Function<Request, Response<T>>。無副作用,易測試、優化。構建響應使用 Response.ok().body(...)。
HandlerFunction<String> helloWorld = request -> Response.ok().body(fromObject("Hello World"));
類型:Function<Request, Optional<HandlerFunction<T>>>。匹配請求並返回處理器。可用 RouterFunctions.route(predicate, handler) 簡化。
RouterFunction<String> route = route(GET("/hello"), handler::helloWorld)
.and(route(GET("/answer"), handler::theAnswer));
支持謂詞組合:method(HttpMethod.GET).and(path("/hello"))。
類型:BiFunction<Request, HandlerFunction<T>, Response<R>>。可攔截請求/響應,實現日誌、安全、緩存。
RouterFunction<?> route = route(GET("/hello"), handler::helloWorld)
.filter((request, next) -> {
System.out.println("Before: " + request.path());
Response<?> resp = next.handle(request);
System.out.println("After: " + resp.body());
return resp;
});
使用 andSame() 保持類型一致性,便於過濾器處理特定響應類型。
HttpServer.create(...)ServletHttpHandlerAdapter + Tomcat無需 Spring ApplicationContext 即可運行,組件可選注入上下文。