我一直在使用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中保存的对象,然后使用Map将其转换为响应实体。我的问题是为什么我在这里使用flatMap而不是map?我从在线示例中获取了此代码,但没有示例解释使用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));
}
}
答案 0 :(得分:2)
HTTP请求的响应是唯一的。您所能做的就是发送Flux
或Mono
作为响应正文,并使用Content-Type
标头让客户端知道它可以作为流使用它{{ 1}}或通常的application/stream+json
。
application/json
和findById(id)
都返回movieRepository.save(existingMovie)
。如果您对其进行映射,则传递到地图的每个事件Mono<Movie>
都会返回Movie
,因此Mono<Movie>
的连接最终会以findById().map(movieRepository.save())
结尾。当你平面映射你基本上&#34;合并&#34;地图中的所有发布商都只有一个Mono<Mono<Movie>>
。
答案 1 :(得分:0)
地图:
@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();
});
}
map
向内部返回的内容添加Mono
,请注意这里accountRepository.save(acc)
返回一个Mono
,如果我不添加block()
,则方法{ {1}}最终返回update
-在这种情况下会编译错误。
flatMap:
Mono<Mono<Account>>
@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);
});
}
仅返回内部返回的任何内容。
希望它有助于以一种非常基本的方式理解它