在弹簧Web通量和反应堆中映射与Flatmap



我一直在使用Spring Boot 2.0.1及其WebFlux库来处理样本反应性Web API。我一直在寻找在线示例来尝试建造它,但我对两件事感到困惑。以下是我有两个问题。

1(如何返回响应实体的通量,当我尝试时,我会发现一个错误,说只能返回一个响应实体。以下是我当前的代码。

@Service
public class MovieServiceImpl implements MovieService {
    @Autowired
    private MovieRepository movieRepository;
    @Override
    public Flux<Movie> list(){
        return movieRepository.findAll();
    }
}
@RestController
public class MovieRestController {
    @Autowired
    private MovieService movieService;
    @GetMapping(value = "/movies")
    public Flux<Movie> list() {
        return movieService.list();
    }
}

2(当我更新一个对象时,我会使用flatmap更新保存在mongo中的对象,然后将其映射到响应实体。我的问题是为什么我在这里使用flatmap而不是地图?我从在线示例中得出了此代码,但是没有示例解释使用Flatmap的使用。我想了解为什么在这里使用它。以下是代码。

@Service
public class MovieServiceImpl implements MovieService {
    @Autowired
    private MovieRepository movieRepository;
    @Override
    public Mono<Movie> update(String id, MovieRequest movieRequest) {
       return movieRepository.findById(id).flatMap(existingMovie -> {
           if(movieRequest.getDescription() != null){
               existingMovie.setDescription(movieRequest.getDescription());
           }
           if(movieRequest.getRating() != null){
               existingMovie.setRating(movieRequest.getRating());
           }
           if(movieRequest.getTitle() != null) {
               existingMovie.setTitle(movieRequest.getTitle());
           }
           return movieRepository.save(existingMovie);
       });
    }
}
@RestController
public class MovieRestController {
    @Autowired
    private MovieService movieService;
    @PutMapping("/movies/{movieId}")
    public Mono<ResponseEntity<Movie>> update(
            @PathVariable("movieId") final String movieId,
            @RequestBody final MovieRequest movieRequest) {
        return movieService.update(movieId, movieRequest)
                .map(m -> new ResponseEntity<>(m, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }
}
  1. HTTP请求的响应是唯一的。您所能做的就是发送FluxMono作为响应的正文,然后使用Content-Type标头让客户知道它可以作为流application/stream+json或通常的application/json

  2. findById(id)movieRepository.save(existingMovie)返回Mono<Movie>。如果映射,每个事件Movie传递给地图将返回Mono<Movie>,以便findById().map(movieRepository.save())的串联以Mono<Mono<Movie>>结束。flatmap时,基本上是将地图中的所有发布者合并到一个Mono中。

地图:

@PutMapping(path="/update/{id}", consumes=MediaType.APPLICATION_JSON_VALUE)
public Mono<Account> update(@PathVariable Long id, @RequestBody Account account) {
    Mono<Account> accFound = accountRepository.findById(id);
    return accFound.map(acc -> {
        acc.setAccountBalance(account.getAccountBalance());
        return accountRepository.save(acc).block();
        });
}

mapMono添加到内部返回的任何内容,请注意accountRepository.save(acc)返回Mono,如果我不添加block(),则方法update最终返回Mono<Mono<Account>>- co_20- compile错误。

flatmap:

@PutMapping(path="/update/{id}", consumes=MediaType.APPLICATION_JSON_VALUE)
public Mono<Account> update(@PathVariable Long id, @RequestBody Account account) {
    Mono<Account> accFound = accountRepository.findById(id);
    return accFound.flatMap(acc -> {
        acc.setAccountBalance(account.getAccountBalance());
        return accountRepository.save(acc);
        });
}

flatMap只需返回内部返回的任何内容即可。

希望它有助于理解它是一种非常基本的方法

最新更新