打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
译:Spring WebFlux:初探 | Spring For All

Spring WebFlux:初探

原文链接:https://dzone.com/articles/spring-webflux-first-steps

作者:Biju Kunjummen

译者:jackzhaiyh

Spring 5 新增WebFlux——在Spring应用中支持响应式编程实践。下面看一下如何将其引入旧版注解风格Controller中。

Spring WebFlux用于表示Spring web层中对Reactive programming的支持。它为服务端创建响应式web应用、也为客户端消费REST服务提供支持。

本文中,我会演示一个采用Spring WebFlux的示例web应用。Spring 5+中的WebFlux支持两种不同编程风格:传统注解风格和新的函数式风格。本文中,我将坚持传统的注解风格,并尝试在另一篇博客中详细描述类似的应用程序,但是以函数式风格定义endpoints。我的重点将是编程模型。

数据和服务层

如下是一个相当简单的REST接口,它支持一个酒店资源的CRUD操作:

public class Hotel { private UUID id; private String name; private String address; private String state; private String zip; ....}

示例中采用Cassandra存储这个entity,并且使用Spring Data Cassandra对响应式编程的支持使数据层获得响应式特性,从而可以支持这样的API。我采用两个repositories,一个便于上面酒店entity的存储,另一个维护可以通过酒店第一个字母进行检索的冗余数据。

public interface HotelRepository { Mono save(Hotel hotel); Mono update(Hotel hotel); Mono findOne(UUID hotelId); Mono delete(UUID hotelId); Flux findByState(String state);}public interface HotelByLetterRepository { Flux findByFirstLetter(String letter); Mono save(HotelByLetter hotelByLetter); Mono delete(HotelByLetterKey hotelByLetterKey);}

返回一个entity实例的操作现在返回一个Mono类型,返回多个entity实例的则返回一个Flux类型。

鉴于此,我简单介绍一种返回响应类型的方法:当更新一个酒店实体时,我必须先删除HotelByLetter存储库维护的冗余数据,然后重新创建一个。这可以通过使用Flux和Mono类型提供的优秀运算符来完成,如下所示:

public Mono update(Hotel hotel) { return this.hotelRepository.findOne(hotel.getId()) .flatMap(existingHotel -> this.hotelByLetterRepository.delete(new HotelByLetter(existingHotel).getHotelByLetterKey()) .then(this.hotelByLetterRepository.save(new HotelByLetter(hotel))) .then(this.hotelRepository.update(hotel))).next();}

Web层

现在回到文章的焦点:支持Web层中基于注解的响应式编程模型支持!

多年来,@Controller@RestController注解一直是Spring MVC的REST endpoint支持的重要组成部分。传统上,他们已经使用多时并返回java POJO。响应模型中的这些控制器已经被调整用来接收和返回Reactive类型——在我的例子中是Mono和Flux——但是另外也支持Rx-java和Reactive Streams类型。

鉴于此,我的Controller如下所示:

@RestController@RequestMapping('/hotels')public class HotelController { .... @GetMapping(path = '/{id}') public Mono get(@PathVariable('id') UUID uuid) { return this.hotelService.findOne(uuid); } @PostMapping public Mono<>> save(@RequestBody Hotel hotel) { return this.hotelService.save(hotel) .map(savedHotel -> new ResponseEntity<>(savedHotel, HttpStatus.CREATED)); } @PutMapping public Mono<>> update(@RequestBody Hotel hotel) { return this.hotelService.update(hotel) .map(savedHotel -> new ResponseEntity<>(savedHotel, HttpStatus.CREATED)) .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)); } @DeleteMapping(path = '/{id}') public Mono<>> delete( @PathVariable('id') UUID uuid) { return this.hotelService.delete(uuid).map((Boolean status) -> new ResponseEntity<>('Deleted', HttpStatus.ACCEPTED)); } @GetMapping(path = '/startingwith/{letter}') public Flux findHotelsWithLetter( @PathVariable('letter') String letter) { return this.hotelService.findHotelsStartingWith(letter); } @GetMapping(path = '/fromstate/{state}') public Flux findHotelsInState( @PathVariable('state') String state) { return this.hotelService.findHotelsInState(state); }}

传统的@RequestMapping、@GetMapping和@PostMapping并没有被改变,变得是返回类型。比如,预期只有一个结果的,现在返回一个Mono类型,之前预期返回一个列表的,现在则返回一个Flux类型。

通过使用Spring Data Cassandra中的响应式支持,整个Web到服务到后端设置都是响应式的,特别针对本文的关注点,非常直观易见。

简单地尝试这篇文章后面的代码可能会更易于理解,你可以在我的GitHub仓库中获得这些代码。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
什么是反应式编程 (Reactive programming)?
求求你别在用SpringMVC了!Spring又官宣了一个牛逼的替代框架!
Spring认证中国教育管理中心-Apache Cassandra 的 Spring 数据教程九
详解响应式技术框架
Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门
生成UUID
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服