本篇文章将继续按照上篇文章基于Spring Webflux 搭建基本代码框架1,完成RouterFunction模式的改造方式。
一、主要改造点
在传统Controller模式下的代码基础上进一步做如下改造:
1、取消Controller入口层,相关入口路径定义转换为router层;
2、取消service业务逻辑层,相关业务逻辑统一收归到handler层,且入参统一为ServerRequest,出参统一为ServerResponse;
3、参数校验等逻辑需要单独自行代码实现;
4、全局异常处理逻辑调整为通过WebExceptionHandler实现;
改造后的代码结构如下:
二、代码实现
(一)Controller入口层改造为router
基于函数式编程模式,应用所有入口路径定义全部在AppRouter配置类中进行定义:
import com.abinge.boot.staging.handler.StudentHandler;
import com.abinge.boot.staging.handler.TeacherHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.*;
@Configuration
public class AppRouter {
@Bean
RouterFunction<ServerResponse> studentRouter(StudentHandler studentHandler){
// 此处就相当于原来StudentController上面的@RequestMapping("/student")
return nest(path("/student"),
// 下面就相当于是原来StudentController类中的各个方法上的@RequestMapping("/add")
route(POST("/add").and(accept(MediaType.APPLICATION_JSON)), studentHandler::add)
.andRoute(POST("/update").and(accept(MediaType.APPLICATION_JSON)), studentHandler::add)
.andRoute(POST("/delete/{id}"), studentHandler::delete)
.andRoute(GET("/queryById/{id}"), studentHandler::queryById)
.andRoute(GET("/queryAll"), studentHandler::queryAll)
);
}
@Bean
RouterFunction<ServerResponse> teacherRouter(TeacherHandler teacherHandler){
// 此处就相当于原来TeacherController上面的@RequestMapping("/teacher")
return nest(path("/teacher"),
// 下面就相当于是原来TeacherController类中的各个方法上的@RequestMapping("/add")
route(POST("/add").and(accept(MediaType.APPLICATION_JSON)), teacherHandler::add)
.andRoute(POST("/update").and(accept(MediaType.APPLICATION_JSON)), teacherHandler::add)
.andRoute(POST("/delete").and(accept(MediaType.APPLICATION_JSON)), teacherHandler::delete)
.andRoute(POST("/queryById").and(accept(MediaType.APPLICATION_JSON)), teacherHandler::queryById)
.andRoute(GET("/queryAll"), teacherHandler::queryAll)
);
}
}