@RestController 和 RouterFunction 的区别
@RestController和RouterFunction是Spring WebFlux框架中用于构建响应式Web应用程序的两种不同的方式。
@RestController:
RouterFunction:
使用方法:
@RestController的使用方法:
RouterFunction的使用方法:
@RestController和RouterFunction是两种不同的编程模型,选择使用哪种方式取决于具体的需求和开发风格。
@RestController 和 RouterFunction 的使用
@RestController示例:
@RestController
@RequestMapping("/example")
public class ExampleController {
@GetMapping
public String getExample() {}
@PostMapping
public String createExample() {}
@PutMapping("/{id}")
public String updateExample(@PathVariable String id) {}
@DeleteMapping("/{id}")
public String deleteExample(@PathVariable String id) {}
}
RouterFunction示例:
首先准备一个测试方法类
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;
/**
* @Author Admin
* @Date 2023/9/5 21:20
* @Description ExampleHandler
**/
@Component
public class ExampleHandler {
public ServerResponse getExample(ServerRequest request) {
// 获取参数信息
String id = request.pathVariable("id");
// 处理获取示例的逻辑
return ServerResponse.ok().body("GET-查询请求, 参数信息:["+id+"]: Get example");
}
public ServerResponse createExample(ServerRequest request) {
// 处理创建示例的逻辑
return ServerResponse.ok().body("POST-创建请求: Create example");
}
public ServerResponse updateExample(ServerRequest request) {
// 获取参数信息
MultiValueMap params = request.params();
// 处理更新示例的逻辑
return ServerResponse.ok()
.body("UPDATE-修改请求, 参数信息:[" + params.toSingleValueMap() + "]: Update example");
}
public ServerResponse deleteExample(ServerRequest request) {
// 接收参数
String delId = request.pathVariable("delId");
// 处理删除示例的逻辑
return ServerResponse.ok().body("Delete-删除请求, 参数信息:[" + delId + "]: Delete example");
}
public ServerResponse getInfo(ServerRequest request) {
// 处理获取示例的逻辑
return ServerResponse.ok().body("GET-查询请求: Get getInfo");
}
}
(1)编写方式一:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.function.RequestPredicates;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.RouterFunctions;
import org.springframework.web.servlet.function.ServerResponse;
import static org.springframework.web.servlet.function.RequestPredicates.GET;
/**
* @Author Admin
* @Description RouterFunction的使用
**/
@Configuration
public class TestController {
@Bean
public RouterFunction routeExampleHandler(ExampleHandler exampleHandler) {
RouterFunctions.Builder route = RouterFunctions.route();
route = route.GET("/example/{id}", exampleHandler::getExample);
route = route.POST("/example", exampleHandler::createExample);
route = route.PUT("/example/update", exampleHandler::updateExample);
route = route.DELETE("/example/{delId}", exampleHandler::deleteExample);
return route.build();
}
}
请求及响应
以上是RouterFunction函数请求增删改查的四种请求方式,也可以换成链式写法:
@Bean
public RouterFunction routeExampleHandler(ExampleHandler exampleHandler) {
return RouterFunctions.route()
.GET("/example", exampleHandler::getExample)
.POST("/example", exampleHandler::createExample)
.PUT("/example/update", exampleHandler::updateExample)
.DELETE("/example/{delId}", exampleHandler::deleteExample)
.build();
}
路由嵌套,RouterFunctions中nest方法
RouterFunction。它可以将一组相关的路由规则进行分组,并将它们作为一个整体应用到主路由上。RouterFunctions.nest的使用示例如下:
@Bean
public RouterFunction mainRouterFunction(ExampleHandler exampleHandler) {
return RouterFunctions.route()
.path("/api", builder -> builder
.nest(RequestPredicates.path("/example"), nestedBuilder -> nestedBuilder
.GET("/{id}", exampleHandler::getExample)
.POST("", exampleHandler::createExample)
)
.GET("/info", exampleHandler::getInfo)
)
.build();
}
在上面的示例中,我们定义了一个mainRouterFunction
方法,返回类型为RouterFunction
。在该方法内,我们使用RouterFunctions.route()
创建主路由构建器,并使用.path()
方法来定义路径匹配规则。
在.path("/api", builder -> builder ...)
中,我们将一组相关的路由规则分组到/api
路径下。然后,在嵌套的.nest(RequestPredicates.path("/example"), nestedBuilder -> nestedBuilder ...)
中,我们将另一组路由规则分组到/api/example
路径下。
通过使用RouterFunctions.nest
,我们可以更好地组织和管理路由规则,使代码结构更清晰,并提高可读性和可维护性。
直接使用RouterFunctions构建一个请求
@Bean
public RouterFunction mainRouterFunction(ExampleHandler exampleHandler) {
return RouterFunctions.route(GET("/api/example/{uid}"),
request -> {
Long uid = Long.valueOf(request.pathVariable("uid"));
return ServerResponse.ok().body("路径 /api/example 参数信息: " + uid);
}
);
}
API文档 RouterFunction
accept(RouterFunctions.Visitor visitor)
接受给定的访问者。
and(RouterFunction
返回一个组合路由函数,该函数首先调用该函数,然后在该路由没有结果的情况下调用另一个函数(相同响应类型T)。
andNest(RequestPredicate predicate, RouterFunction
如果路由不匹配且给定的请求谓词适用,则返回一个组成的路由函数,该函数会路由到给定的路由器函数。
andOther(RouterFunction> other)
返回一个组成的路由函数,该函数首先调用此函数,如果此路由没有结果,则调用另一个函数(不同响应类型)。
andRoute(RequestPredicate predicate, HandlerFunction
如果路由不匹配且给定的请求谓词适用,则返回一个组成的路由函数,该函数会路由到给定的处理函数。
filter(HandlerFilterFunction
使用给定的过滤函数过滤此函数路由的所有处理函数。
route(ServerRequest request)
返回与给定请求匹配的处理函数。
withAttribute(String name, Object value)
返回一个带有给定属性的新路由函数。
withAttributes(Consumer
API文档链接 RouterFunction
RouterFunction 实现原理:
1、路由器函数注册:通过 RouterFunctions 类的静态方法创建 RouterFunction 对象,并使用路由器函数将请求映射到处理程序函数上。
2、请求匹配:当收到一个 HTTP 请求时,Spring WebFlux 框架会根据请求的 URL、HTTP 方法等信息进行匹配。
3、处理程序函数执行:一旦找到与请求匹配的路由器函数,框架会调用相应的处理程序函数来处理请求。处理程序函数可以是一个 Lambda 表达式、方法引用或其他函数式编程方式定义的函数。
4、响应生成:处理程序函数执行完成后,会生成一个响应对象,包含要返回给客户端的数据和相关的 HTTP 状态码、头部信息等。
5、响应发送:最后,框架将生成的响应发送给客户端。