一、函数式 Web
在 Spring Boot 中,使用函数式 Web(Function-based Web)可以通过 RouterFunction
和 HandlerFunction
来定义路由和请求处理逻辑。这种方式与传统的注解驱动的方式不同,它更加简洁,并且适合响应式编程。下面是一个简单的示例,展示如何在 Spring Boot 中使用函数式 Web 编程。
SpringMVC 5.2 以后允许使用函数式的方式,定义 Web 的请求处理流程。
函数式接口。
Web 请求处理的方式:
1、@Controller + @RequestMapping:耦合式(路由、业务耦合)。
2、函数式 Web:分离式(路由、业务分离)。
场景
User RESTful - CRUD。
- GET /user/1 获取 1 号用户。
- GET /users 获取所有用户。
- POST /user 请求体携带 JSON,新增一个用户。
- PUT /user/1 请求体携带 JSON,修改 1 号用户。
- DELETE /user/1 删除 1 号用户。
1. 引入依赖
要使用函数式 Web 功能,需要在项目中引入 Spring WebFlux 的依赖。你可以通过以下方式引入
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
2. 定义请求处理器和路由
import com.myxh.springboot.web.biz.UserBizHandler;
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;/*** @author MYXH* @date 2023/9/18* @description* 场景:User RESTful - CRUD* GET /user/1 获取 1 号用户* GET /users 获取所有用户* POST /user 请求体携带 JSON,新增一个用户* PUT /user/1 请求体携带 JSON,修改 1 号用户* DELETE /user/1 删除 1 号用户*/
@Configuration
public class WebFunctionConfig
{/*** 函数式 Web* 1、给容器中放一个 Bean: 类型是 RouterFunction<ServerResponse>,集中所有路由信息* 2、每个业务准备一个自己的 Handler* <br>* 核心四大对象* 1、RouterFunction:定义路由信息,发什么请求,谁来处理* 2、RequestPredicate:定义请求,请求谓语,请求方式(GET、POST),请求参数* 3、ServerRequest:封装请求完整数据* 4、ServerResponse:封装响应完整数据** @param userBizHandler 用户业务处理程序(userBizHandler 会被自动注入进来)* @return routerFunction 路由器功能*/@Beanpublic RouterFunction<ServerResponse> userRouter(UserBizHandler userBizHandler){// 开始定义路由信息RouterFunction<ServerResponse> routerFunction = RouterFunctions.route().GET("/user/{id}", RequestPredicates.accept(MediaType.ALL), userBizHandler::getUser).GET("/users", userBizHandler::getUsers).POST("/user", RequestPredicates.accept(MediaType.APPLICATION_JSON), userBizHandler::saveUser).PUT("/user{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), userBizHandler::updateUser).DELETE("/user{id}", userBizHandler::deleteUser).build();return routerFunction;}
}
3、业务处理使用
package com.myxh.springboot.web.biz;import com.myxh.springboot.web.bean.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;import java.util.Arrays;
import java.util.List;/*** @author MYXH* @date 2023/9/18* @description 专门处理 User 有关的业务*/
@Slf4j
@Service
public class UserBizHandler
{@Autowiredprivate User user;/*** 查询指定 id 的用户** @param request 请求* @return response 响应* @throws Exception 异常*/public ServerResponse getUser(ServerRequest request) throws Exception{// 业务处理String id = request.pathVariable("id");user.setId(1L);user.setUserName("MYXH");user.setPassword("520.ILY!");user.setAge(21);user.setEmail("1735350920@qq.com");log.info("查询 {} 号用户信息成功", id);// 构造响应ServerResponse response = ServerResponse.ok()// 凡是 body 中的对象,就是以前 @ResponseBody 原理,利用 HttpMessageConverter 写出为 json.body(user);return response;}/*** 获取所有用户** @param request 请求* @return response 响应* @throws Exception 异常*/public ServerResponse getUsers(ServerRequest request) throws Exception{// 业务处理List<User> userList = Arrays.asList(new User(1L, "MYXH","520.ILY!",21,"1735350920@qq.com","root"),new User(2L, "root","000000",21,"root@qq.com","root"),new User(3L, "admin","123456",21,"admin@qq.com","admin"),new User(4L, "test","test",18,"test@qq.com","test"),new User(5L, "张三","123456",18,"","user"));log.info("查询所有用户信息成功");// 构造响应ServerResponse response = ServerResponse.ok().body(userList);return response;}/*** 保存用户** @param request 请求* @return response 响应* @throws Exception 异常*/public ServerResponse saveUser(ServerRequest request) throws Exception{// 业务处理// 提取请求体User body = request.body(User.class);log.info("保存用户信息成功,用户信息:{}", body);// 构造响应ServerResponse response = ServerResponse.ok().build();return response;}/*** 更新指定 id 的用户** @param request 请求* @return response 响应* @throws Exception 异常*/public ServerResponse updateUser(ServerRequest request) throws Exception{// 业务处理// 提取请求体User body = request.body(User.class);log.info("更新用户信息成功,用户信息:{}", body);// 构造响应ServerResponse response = ServerResponse.ok().build();return response;}/*** 删除指定 id 的用户** @param request 请求* @return response 响应* @throws Exception 异常*/public ServerResponse deleteUser(ServerRequest request) throws Exception{// 业务处理String id = request.pathVariable("id");log.info("删除 {} 号用户信息成功", id);// 构造响应ServerResponse response = ServerResponse.ok().build();return response;}
}
核心类介绍
- RouterFunction
- RequestPredicate
- erverRequest
- ServerResponse