• 重生之 SpringBoot3 入门保姆级学习(16、函数式 Web 编程)


    重生之 SpringBoot3 入门保姆级学习(16、函数式 Web 编程)

    3.4 函数式 Web


    个人写过 go 类似于 go + gin 框架

    1、场景

    场景: User RESTful - CRUD

    1. GET/user/1 获取1号用户
    2. GET/users 获取所有用户
    3. POST/user 清求体携带JSON,新增一个用户
    4. PUT/user/1 请求体携带JSON,修改1号用户
    5. DELETE/user/1删除1号用户

    2、核心类

    • RouterFunction: 定义路由信息(发什么请求,谁来处理)
    • RequestPredicate: 定义请求规则:请求谓语、请求方式(GET、POST)、请求参数
    • ServerRequest: 封装请求完整的数据
    • ServerResponse: 封装响应完整的数据

    3、实战

    • 新建 Person 类
    package com.zhong.web.dto;
    
    import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @ClassName : Person
     * @Description :
     * @Author : zhx
     * @Date: 2024-06-02 13:05
     */
    @JacksonXmlRootElement // 加入注解使其可以输出 xml
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Person {
        private Integer id;
        private String userName;
        private String like;
        private Integer age;
    }
    
    • 新建 WebFuntionConfig 建立所有路由与函数的映射
    package com.zhong.web.config;
    
    import com.zhong.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.*;
    
    /**
     * @ClassName : WebFuntionConfig
     * @Description :
     * @Author : zhx
     * @Date: 2024-06-02 15:31
     */
    @Configuration
    public class WebFunctionConfig {
        /**
         * 函数式 web:
         * 1、给容器中仿一个 Bean: 类型是 RouterFunction 集中所有路由与对应处理函数信息
         * 2、给每个业务准备应该 Handler
         *
         * 核心四大对象:
         *      1、RouterFunction:   定义路由信息(发什么请求,谁来处理)
         *      2、RequestPredicate: 定义请求规则:请求谓语、请求方式(GET、POST)、请求参数
         *      3、ServerRequest:    封装请求完整的数据
         *      4、ServerResponse:   封装响应完整的数据
         */
    
        @Bean
        public RouterFunction<ServerResponse> userRouter(UserBizHandler userBizHandler) {
    
            return RouterFunctions.route()     // 开始定义路由信息
                    .GET("/user/{id}", RequestPredicates.accept(MediaType.ALL), userBizHandler::getUser)
                    .GET("/users", userBizHandler::getUserAll)
                    .POST("/user", RequestPredicates.accept(MediaType.APPLICATION_JSON), userBizHandler::addUser)
                    .PUT("/user/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), userBizHandler::updateUser)
                    .DELETE("/user/{id}", userBizHandler::deleteUser)
                    .build();
    
        }
    }
    
    • 新建 UserBizHandler 处理路由对应的函数处理方法(业务逻辑)
    package com.zhong.web.biz;
    
    import com.zhong.web.dto.Person;
    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 java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @ClassName : UserBizHandler
     * @Description :
     * @Author : zhx
     * @Date: 2024-06-02 15:40
     */
    @Slf4j
    @Service
    public class UserBizHandler {
        public ServerResponse getUser(ServerRequest request) {
            String id = request.pathVariable("id");
            log.info("查询的用户id为 [{}] ", id);
            // 业务处理
            Person person = new Person(1, "小钟", "小王", 23);
            // 构造响应
            return ServerResponse
                    .ok()
                    .body(person);
        }
    
        public ServerResponse getUserAll(ServerRequest serverRequest) {
            log.info("查询所有用户成功!");
            List<Person> users = Arrays.asList(
                    new Person(1, "小钟", "小王", 23),
                    new Person(1, "小王", "小钟", 21));
            return ServerResponse
                    .ok()
                    .body(users);
        }
    
        public ServerResponse addUser(ServerRequest serverRequest) throws ServletException, IOException {
            Object body = serverRequest.body(Person.class);
            log.info("添加用户成功");
            return ServerResponse
                    .ok()
                    .body(body);
        }
    
    
        public ServerResponse updateUser(ServerRequest serverRequest) throws ServletException, IOException {
            Object body = serverRequest.body(Person.class);
            log.info("更新用户成功");
            return ServerResponse
                    .ok()
                    .body(body);
        }
    
        public ServerResponse deleteUser(ServerRequest serverRequest) {
            String id = serverRequest.pathVariable("id");
            log.info("删除用户 【{}】成功!", id);
            return ServerResponse
                    .ok()
                    .body(id);
        }
    }
    
    • 重新启动项目使用 Postman 测试
    • 根据 id 查询单个用户
    http://localhost:8080/user/1
    

    image-20240602160529097

    • 查询所有用户
    http://localhost:8080/users
    

    image-20240602160604973

    • 添加用户
    http://localhost:8080/user
    

    image-20240602160759439

    • 修改用户
    http://localhost:8080/user/1
    

    image-20240602161159139

    • 删除用户
    localhost:8080/user/1
    

    image-20240602161257262

    • log 日志

    image-20240602161336680

  • 相关阅读:
    进程调度的原理和算法探析
    STM32 ST-LINK
    NANK新旗舰首发!南卡Pro4骨传导耳机配置新升级!新的音质天花板
    呀!这款markdown编辑器我太中意啦!
    【Linux】多进程编程
    IDEA配置自己的Maven以及创建Maven
    CAD一键添加审图批注、AUTOCAD——图形界线怎么设置
    数据面最流行的工具包dpdk的前世-现在和未来
    NSSCTF web 刷题记录2
    springboot入门
  • 原文地址:https://blog.csdn.net/weixin_56050344/article/details/139393065