继续Spring Webflux,今天来实操RouterFunction的写法,代替原先传统的Controller


继续Spring Webflux,今天来实操RouterFunction的写法,代替原先传统的Controller

继续Spring Webflux,今天来实操RouterFunction的写法,代替原先传统的Controller


Spring Webflux同时支持传统的Controller方式,也支持一种新的实现方式,RouterFunction方式,这种方式更纯粹。

Router Function

开发过程:

HandlerFunction(输入ServerRequest返回ServerResponse)

->RouterFunction(请求URL和HandlerFunction对应起来)

->HttpHandler

->Server处理

@FunctionalInterface
public interface HandlerFunction<T extends ServerResponse{
    Mono<T> handle(ServerRequest var1);
}

依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
        </dependency>

编写handler

@Component
public class UserHandler {

    private final UserRepository userRepository;

    public UserHandler(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * 得到所有用户
     * @param var1
     * @return
     */

    public Mono<ServerResponse> getAllUserHandle(ServerRequest var1){
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
                .body(this.userRepository.findAll(), User.class);
    }

    /**
     * 新增用户
     * @param var1
     * @return
     */

    public Mono<ServerResponse> putUserHandle(ServerRequest var1){
        Mono<User> user = var1.bodyToMono(User.class);
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
                //save方法不支持Mono对象,因此需要调用saveAll方法,该方法可以传入Publisher对象,而mono和flux都是Publisher对象
                .body(this.userRepository.saveAll(user), User.class);
    }

    /**
     * 根据ID删除用户
     * @param var1
     * @return
     */

    public Mono<ServerResponse> getUserHandle(ServerRequest var1){
        String id = var1.pathVariable("id");
//        return ServerResponse.ok().body(this.userRepository.findById(id), User.class)
//                ;
        return this.userRepository.findById(id)
                //这块用map有异常
                .flatMap(u->ServerResponse.ok().body(Mono.just(u),User.class))
                //原先使用的defaultIfEmpty 这里不能用
                .switchIfEmpty(ServerResponse.notFound().build())
;
    }

    /**
     * 根据ID删除用户
     * @param var1
     * @return
     */

    public Mono<ServerResponse> deleteUserHandle(ServerRequest var1){
        String id = var1.pathVariable("id");
        return this.userRepository.findById(id)
                .flatMap(u -> this.userRepository.delete(u)
                        .then(ServerResponse.ok().build()))
                        //原先使用的defaultIfEmpty 这里不能用
                        .switchIfEmpty(ServerResponse.notFound().build());
    }
}

配置

/**
 * @author: yunho
 * @date: 2021/5/13 15:02
 * @description: 类似于spring mvc的dispatch
 * 是将用户的uri和router function对应起来
 */

@Configuration
public class AllRouters {

    @Bean
    RouterFunction<ServerResponse> userRouter(UserHandler userHandler) {
        //注意引入包的时候要引用org.springframework.web.reactive下的对象
        return RouterFunctions
                //嵌套
                .nest(
                        //相当于@RequestMapping("/user")
                        RequestPredicates.path("/ruser"),
                        //相当于@GetMapping(value = "/")
                        RouterFunctions.route(
                                //获取所有用户
                                RequestPredicates.GET("/"),
                                userHandler::getAllUserHandle
                        )
                                .andRoute(
                                        //新增用户
                                        RequestPredicates.POST("/")
                                                .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),
                                        userHandler::putUserHandle
                                )
                                .andRoute(
                                        RequestPredicates.DELETE("/{id}"),
                                        userHandler::deleteUserHandle
                                )
                                .andRoute(
                                        RequestPredicates.GET("/{id}"),
                                        userHandler::getUserHandle
                                )
                );
    }
}

这样就全部完成了我们的RouterFunction方式的web代码编写,还是很简单的。注意:是在上一篇webflux基础上编写的,可以直接参考码云的代码:核心代码在码云:https://gitee.com/josekongng/stream-reactive-webflux-learn


原文始发于微信公众号(云户):继续Spring Webflux,今天来实操RouterFunction的写法,代替原先传统的Controller

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/25879.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!