0 概述
- 随着技术的不断演进,SpringBoot 作为 Java 生态中最流行的微服务框架之一,一直在不断地创新和改进。在 SpringBoot3 中,一个引人注目的新特性就是函数式 Web,它为开发者提供了一种全新的、更简洁的方式来构建 Web 应用程序。
1 什么是函数式 Web
- 函数式 Web 并不是指使用函数式编程语言(如 Haskell 或 Scala)来编写 Web 应用,而是在现有的编程范式中融入函数式编程的思想。在 SpringBoot3 的上下文中,函数式 Web 允许开发者通过定义一系列的函数来处理 HTTP 请求和响应,而不是传统的基于注解的控制器方法。
-
核心的四大对象
- RouterFunction:定义路由信息,发什么请求,哪个 Handler 来处理
- RequestPredicate:定义请求方式,GET、POST 等
- ServerRequest:请求数据
- ServerResponse:响应数据
2 为什么要使用函数式编程
- 简洁性:函数式 Web 减少了样板代码,让开发者能够更专注于业务逻辑的实现
- 灵活性:通过组合不同的函数,可以轻松地构建复杂的 Web 应用程序
- 测试性:由于函数式编程的特点,每个函数都可以单独测试,提高了代码的可测试性
- 声明式编程:鼓励声明式地描述应用程序的行为,这有助于提高代码的可读性和可维护性
3 使用演示
- SpringBoot3 通过 WebFlux.fn 模块提供了对函数式 Web 的支持。可以使用 HandlerFunction 接口来实现处理函数,并使用 RouterFunction 来定义路由规则
- 定义 Bean 对象,集中所有路由规则信息
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; 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 top.ezjava.java17demo.biz.UserBizHandler; /** * @Author Jasper * @Time 2024/02/25 * @公众号:EzCoding */ @Configuration public class WebFunctionConfig { @Bean public RouterFunction<ServerResponse> userRoute(UserBizHandler userBizHandler) { return RouterFunctions.route() // 开始定义路由信息 .GET("/user/{id}", RequestPredicates.a***ept(MediaType.ALL), userBizHandler::getUser) .GET("/userList", userBizHandler::getUserList) .POST("/user/addUser", RequestPredicates.a***ept(MediaType.APPLICATION_JSON), userBizHandler::addUser) .POST("/user/delUser", userBizHandler::delUser) .build(); } }
- User 实体类
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @Author Jasper * @Time 2024/02/25 * @公众号:EzCoding */ @AllArgsConstructor @NoArgsConstructor @Data public class User { private Long id; private String name; private String password; private String sex; private Integer age; public User(String name, String password) { this.name = name; this.password = password; } }
- 下面定义一个 User 相关的 CRUD 业务类
import jakarta.servlet.ServletException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; import top.ezjava.java17demo.pojo.User; import java.io.IOException; import java.util.Arrays; import java.util.List; /** * @Author Jasper * @Time 2024/02/25 * @公众号:EzCoding */ @Service @Slf4j public class UserBizHandler { /** * 查询指定id的用户 */ public ServerResponse getUser(ServerRequest request) { String id = request.pathVariable("id"); log.info("查询【{}】用户信息", id); // 业务处理 User user = new User(1L, "Jasper", "v50","男", 30); // 构造响应 return ServerResponse.ok().body(user); } /** * 查询用户列表 */ public ServerResponse getUserList(ServerRequest request) { log.info("查询用户列表"); // 业务处理 List<User> userList = Arrays.asList( new User(1L, "Jasper", "v50","男", 30), new User(2L, "Lucy", "v80","女", 18) ); // 构造响应 return ServerResponse.ok().body(userList); } /** * 新增用户 */ public ServerResponse addUser(ServerRequest request) throws ServletException, IOException { User body = request.body(User.class); log.info("新增用户成功:{}", body); return ServerResponse.ok().build(); } /** * 删除用户 */ public ServerResponse delUser(ServerRequest request) { String id = request.param("id").orElse(""); log.info("删除【{}】用户信息", id); return ServerResponse.ok().build(); } }
- 启动服务,访问测试:localhost:8888/userList,结果如下
- 以上就是函数式 Web 的全部内容了,收藏起来学习,卷起来
- 创作不易,感谢阅读,若您喜欢这篇文章,不妨传承这份知识的力量,点个赞关注我吧~
- 微信公众号:EzCoding