当前位置: 首页 > 科技观察

SpringWebFlux使用函数式编程的HandlerFunction

时间:2023-03-12 04:21:24 科技观察

本文主要内容:RouterFunction使用概述Router函数用于将请求路由到对应的HandlerFunction。通常,您不需要自己编写路由器功能,而是使用RouterFunctions类中的方法来创建一个。RouterFunctions.route()(无参数)为创建路由器函数提供了流畅的构建器,而RouterFunctions.route(RequestPredicate,HandlerFunction)提供了用于创建路由器的直接方法。一般来说,推荐使用route()构建器,因为它为典型的映射场景提供了方便的快捷方式,而不需要难以找到的静态导入。例如,路由器功能构建器提供方法GET(String,HandlerFunction)来为GET请求创建映射;POST和POST(String,HandlerFunction)。除了基于HTTP方法的映射之外,路由构建器还提供了一种在映射到请求时引入额外谓词的方法。对于每个HTTP方法,都有一个以RequestPredicate作为参数的重载变体,尽管可以表达额外的约束。Predicates你可以自己写RequestPredicates,但是RequestPredicates类提供了基于请求路径、HTTP方法、内容类型等的通用实现。下面的例子使用请求谓词创建基于Accept头的约束:RouterFunctionroute=RouterFunctions.route().GET("/hello-world",accept(MediaType.TEXT_PLAIN),request->ServerResponse.ok().bodyValue("HelloWorld")).build();您可以使用以下方法将多个请求谓词组合在一起:RequestPredicate.and(RequestPredicate)//两者必须匹配。RequestPredicate.or(RequestPredicate)//都可以匹配。RequestPredicates中的许多谓词都是复合的。例如,RequestPredicates.GET(String)由RequestPredicates.method(HttpMethod)和RequestPredicates.path(String)组成。上面显示的示例还使用了两个请求谓词,因为构建器在内部使用RequestPredicates.GET并将其与接受谓词组合。路由路由器功能按顺序评估:如果第一条路由不匹配,则评估第二条路由,依此类推。因此,在一般路由之前声明更具体的路由是有意义的。这在将路由器功能注册为Springbean时也很重要,这将在后面描述。请注意,此行为不同于基于注释的编程模型,后者会自动选择“最具体”的控制器方法。当使用路由函数构建器时,所有定义的路由都被组合到一个从build()返回的RouterFunction中。还有其他方法可以将多个路由器功能组合在一起:在RouterFunctions.route()构建器上添加(RouterFunction)。路由器功能。和(路由器功能)。RouterFunction.andRoute(RequestPredicate,HandlerFunction)?—?具有嵌套RouterFunctions.route()的RouterFunction.and()的快捷方式。下面的例子展示了四个路由的组合:PersonH??andler(repository);RouterFunctionotherRoute=...RouterFunctionroute=route().GET("/person/{id}",accept(APPLICATION_JSON),handler::getPerson)//1.GET("/person",accept(APPLICATION_JSON),handler::listPeople)//2.POST("/person",handler::createPerson)//3.add(otherRoute)//4.build();与JSON的Accept标头匹配的GET/person/{id}被路由到PersonH??andler.getPerson。带有匹配JSON的Accept标头的GET/person被路由到PersonH??andler.listPeople。没有附加谓词的POST/person映射到PersonH??andler.createPerson。otherRoute是在别处创建并添加到构建的路由中的路由器功能。嵌套路由一组路由器功能通常有一个共享谓词,例如共享路径。在上面的示例中,共享谓词将是匹配/person的路径谓词,由三个路由使用。这种重复可以通过在使用注解时使用映射到/person的类型级@RequestMapping注解来消除。在WebFlux.Fn中,可以通过路由器功能构建器上的路径方法共享路径谓词。例如,可以通过以下方式使用嵌套路由来改进上面示例的最后几行:RouterFunctionroute=route().path("/person",builder->builder//1.GET("/{id}",accept(APPLICATION_JSON),handler::getPerson).GET(accept(APPLICATION_JSON),handler::listPeople).POST(handler::createPerson)).build();注意:path的第二个参数是接受路由器构建器的消费者。虽然基于路径的嵌套是最常见的,但您可以通过在构建器上使用nest方法来嵌套任何类型的谓词。上面仍然包含一些以共享Accept-header谓词形式出现的重复。我们可以通过使用nest方法进一步改进它并接受:RouterFunctionroute=route().path("/person",b1->b1.nest(accept(APPLICATION_JSON),b2->b2.GET("/{id}",handler::getPerson).GET(handler::listPeople)).POST(handler::createPerson)).build();总结:路由功能中RouteFunction的使用。使用嵌套路由。