继续Spring Webflux,今天来实操一般传统的Controller改造


继续Spring Webflux,今天来实操一般传统的Controller改造


不管什么新概念,新技术也好,都需要一行一行的代码撸出来,动手实操才能真正掌握。

完整示例

使用@Controller和@RequestMapping…

依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
            <version>2.3.6.RELEASE</version>
        </dependency>
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
            <version>2.3.6.RELEASE</version>
        </dependency>
  <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

主启动类添加@EnableReactiveMongoRepositories注释,开启响应式MongoDB资源

配置:

spring:
  data:
    mongodb:
      uri: mongodb://192.168.3.210:27017/webflux #uri和其他项只能选择一个配置 否则会冲突
      username: admin
      password: xxxx

异常:

Invalid mongo configuration, either uri or host/port/credentials must be specified

启动报错,原因是我在配置时 配置了URI,还配置的username和password,资料显示,要么配置uri,要么配置其他项,否则会冲突

正确配置如下:

spring:
  data:
    mongodb:
      uri: mongodb://root:123456@192.168.3.210:27017/webflux

mongodb相关操作省略, 可以到菜鸟教程学习。

编码:

核心代码在码云:https://gitee.com/josekongng/stream-reactive-webflux-learn

编写实体类:

//相当于关系型数据库中的表
@Document(collection = "user")
@Data
public class User {
    @Id
    private String id;

    private String name;

    private int age;
}

编写Repository实现:

@Repository
public interface UserRepository extends ReactiveMongoRepository<User,String> {
    Flux<User> findByAgeBetween(int start, int end);
    @Query("{'age':{'$gte':30,'$lte':40}}")
    Flux<User> userOld();
}

编写Controller:

 @PostMapping("/")
    public Mono<User> putUser(@RequestBody User user){
        //spring data jpa 中 新增和修改都是save,有id为修改,无id为新增
        //需要自行判断是否将ID置空
//        user.setId(null);
        return this.userRepository.save(user);
    }
    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> deleteUser(@PathVariable String id){
        //deleteByID 没有返回值,不能判断是否正常删除
        return this.userRepository.findById(id)
                //当要操作数据,并返回一个mono 使用flatmap
                //如果不操作数据,只是做转换
                .flatMap(user->this.userRepository.delete(user)
                        .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK))))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }
    @PutMapping("/")
    public Mono<ResponseEntity<User>> updateUser(@RequestBody User user){
//        return this.userRepository.save(user); //不直接这么写 是因为有可能由于前端逻辑问题导致id传错或未传,从而引起服务异常,而且不容易找问题
        return this.userRepository.findById(user.getId())
                .flatMap(user1 -> {
                    user1.setName(user.getName());
                    user1.setAge(user.getAge());
                    return this.userRepository.save(user1);
                })
                .map(u -> new ResponseEntity<User>(u,HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @GetMapping("/{id}")
    public Mono<ResponseEntity<User>> findUser(@PathVariable String id){
//        return this.userRepository.save(user); //不直接这么写 是因为有可能由于前端逻辑问题导致id传错或未传,从而引起服务异常,而且不容易找问题
        return this.userRepository.findById(id)
                .map(u -> new ResponseEntity<User>(u,HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @GetMapping("/age/{start}/{end}")
    public Flux<User> findUser(@PathVariable int start,@PathVariable int end){
//        return this.userRepository.save(user); //不直接这么写 是因为有可能由于前端逻辑问题导致id传错或未传,从而引起服务异常,而且不容易找问题
        return this.userRepository.findByAgeBetween(start,end);
    }

    @GetMapping(value = "/stream/age/{start}/{end}",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> findUserStram(@PathVariable int start,@PathVariable int end){
//        return this.userRepository.save(user); //不直接这么写 是因为有可能由于前端逻辑问题导致id传错或未传,从而引起服务异常,而且不容易找问题
        return this.userRepository.findByAgeBetween(start,end);
    }

    @GetMapping("/old")
    public Flux<User> findUserOld(){
//        return this.userRepository.save(user); //不直接这么写 是因为有可能由于前端逻辑问题导致id传错或未传,从而引起服务异常,而且不容易找问题
        return this.userRepository.userOld();
    }

    @GetMapping(value = "/stream/old",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> findUserOldStram(){
//        return this.userRepository.save(user); //不直接这么写 是因为有可能由于前端逻辑问题导致id传错或未传,从而引起服务异常,而且不容易找问题
        return this.userRepository.userOld();
    }

总结:

Mono返回一个数据,Flux返回多个

采用响应式流方式需要设置媒体类型:@GetMapping(value = “/stream/old”,produces = MediaType.TEXT_EVENT_STREAM_VALUE)

spring-data-jpa很好用,但是需要加深学习

lambda和stream的编码方式要加深学习


原文始发于微信公众号(云户):继续Spring Webflux,今天来实操一般传统的Controller改造

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

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

(0)
小半的头像小半

相关推荐

发表回复

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