在上一篇文章中,我介绍了Spring Web-Flux的基础知识,它表示Spring框架的Web层中的响应式支持。

我已经展示了使用Spring Data Cassandra并在Spring Web Layers中使用传统注释支持的端到端示例, 大致如下:

...
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
...@RestController
@RequestMapping("/hotels")
public class HotelController {@GetMapping(path = "/{id}")public Mono<Hotel> get(@PathVariable("id") UUID uuid) {...}@GetMapping(path = "/startingwith/{letter}")public Flux<HotelByLetter> findHotelsWithLetter(@PathVariable("letter") String letter) {...}}

除了返回类型外,这看起来像传统的Spring Web注释,这些端点不是返回域类型,而是通过在Reactor-Core中实现Mono和Flux的实现返回Publisher类型,而Spring-Web则将内容流回。

在本文中,我将介绍一种不同的公开端点的方法-使用功能样式而不是注释样式。 让我承认,对于我了解暴露Web终结点的功能样式的理解,我发现Baeldung的文章和Rossen Stoyanchev的文章非常宝贵。

将注释映射到路线

让我从一些基于注释的端点开始,一个是检索实体,另一个是保存实体:

@GetMapping(path = "/{id}")
public Mono<Hotel> get(@PathVariable("id") UUID uuid) {return this.hotelService.findOne(uuid);
}@PostMapping
public Mono<ResponseEntity<Hotel>> save(@RequestBody Hotel hotel) {return this.hotelService.save(hotel).map(savedHotel -> new ResponseEntity<>(savedHotel, HttpStatus.CREATED));
}

在公开端点的功能风​​格中,每个端点都将转换为RouterFunction ,它们可以组成以创建应用程序的所有端点,如下所示:

package cass.web;import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.*;public interface ApplicationRoutes {static RouterFunction<?> routes(HotelHandler hotelHandler) {return nest(path("/hotels"),nest(accept(MediaType.APPLICATION_JSON),route(GET("/{id}"), hotelHandler::get).andRoute(POST("/"), hotelHandler::save)));}
}

有一些辅助功能(嵌套,路由,GET,接受等),可以轻松地将所有RouterFunction组合在一起。 找到合适的RouterFunction后,该请求由HandlerFunction处理,该函数在上述示例中由HotelHandler抽象,并且保存和获取功能如下所示:

import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.util.UUID;@Service
public class HotelHandler {...public Mono<ServerResponse> get(ServerRequest request) {UUID uuid = UUID.fromString(request.pathVariable("id"));Mono<ServerResponse> notFound = ServerResponse.notFound().build();return this.hotelService.findOne(uuid).flatMap(hotel -> ServerResponse.ok().body(Mono.just(hotel), Hotel.class)).switchIfEmpty(notFound);}public Mono<ServerResponse> save(ServerRequest serverRequest) {Mono<Hotel> hotelToBeCreated = serverRequest.bodyToMono(Hotel.class);return hotelToBeCreated.flatMap(hotel ->ServerResponse.status(HttpStatus.CREATED).body(hotelService.save(hotel), Hotel.class));}...
}

这是原始基于注释的项目支持的所有API的完整RouterFunction的样子:

import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.*;public interface ApplicationRoutes {static RouterFunction<?> routes(HotelHandler hotelHandler) {return nest(path("/hotels"),nest(accept(MediaType.APPLICATION_JSON),route(GET("/{id}"), hotelHandler::get).andRoute(POST("/"), hotelHandler::save).andRoute(PUT("/"), hotelHandler::update).andRoute(DELETE("/{id}"), hotelHandler::delete).andRoute(GET("/startingwith/{letter}"), hotelHandler::findHotelsWithLetter).andRoute(GET("/fromstate/{state}"), hotelHandler::findHotelsInState)));}
}

测试功能路线

测试这些路由也很容易,Spring Webflux提供了一个WebTestClient来测试路由,同时提供模拟其背后的实现的能力。

例如,为了测试通过ID的get端点,我将WebTestClient绑定到之前定义的RouterFunction,并使用它提供的断言来测试行为。

import org.junit.Before;
import org.junit.Test;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;import java.util.UUID;import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;public class GetRouteTests {private WebTestClient client;private HotelService hotelService;private UUID sampleUUID = UUID.fromString("fd28ec06-6de5-4f68-9353-59793a5bdec2");@Beforepublic void setUp() {this.hotelService = mock(HotelService.class);when(hotelService.findOne(sampleUUID)).thenReturn(Mono.just(new Hotel(sampleUUID, "test")));HotelHandler hotelHandler = new HotelHandler(hotelService);this.client = WebTestClient.bindToRouterFunction(ApplicationRoutes.routes(hotelHandler)).build();}@Testpublic void testHotelGet() throws Exception {this.client.get().uri("/hotels/" + sampleUUID).exchange().expectStatus().isOk().expectBody(Hotel.class).isEqualTo(new Hotel(sampleUUID, "test"));}
}

结论

定义路由的功能方式绝对不同于基于注释的方式–我喜欢这是定义端点以及如何处理端点调用的更为明确的方式,注释总是给人更多的感觉。神奇。

我在github存储库中有完整的工作代码,它可能比本文中的代码更容易遵循。

翻译自: https://www.javacodegeeks.com/2017/04/spring-web-flux-functional-style-cassandra-backend.html

Spring Web-Flux – Cassandra后端的功能样式相关推荐

  1. spring flux_Spring Web-Flux – Cassandra后端的功能样式

    spring flux 在上一篇文章中,我介绍了Spring Web-Flux的基础知识,它表示Spring框架的Web层中的响应式支持. 我已经展示了使用Spring Data Cassandra并 ...

  2. Spring Web flux基础(一)

    1.SpringWebflux 介绍 (1)是 Spring5 添加新的模块,用于 web 开发的,功能和 SpringMVC 类似的,Webflux 使用 当前一种比较流行响应式编程出现的框架. ( ...

  3. Spring系列学习之Spring Web Services

    英文原文:https://spring.io/projects/spring-ws 目录 概述 特性 Spring Boot配置 快速开始 学习 文档 概述 Spring Web Services(S ...

  4. Spring Web(第一部分)

    1. Spring Web MVC Spring Web MVC是在Servlet API上构建的原始Web框架,从一开始就包含在Spring框架中.其正式名称"Spring Web MVC ...

  5. spring(5)构建 spring web 应用程序

    [0]README 1)本文部分文字描述转自:"Spring In Action(中/英文版)",旨在review  "spring(5)构建 spring web 应用 ...

  6. Spring Boot swagger之前后端分离

    前后端分离详解 现在的趋势发展,需要把前后端开发和部署做到真正的分离做前端的谁也不想用Maven或者Gradle作为构建工具做后端的谁也不想要用Grunt或者Gulp作为构建工具 前后端需要通过接口来 ...

  7. Web前端和后端的区别是什么?如何区分?

    Web前端和后端的区别是什么?如何区分?从前端和后端两者工作内容和负责项目是完全不同.后端:入门难深入更难,枯燥乏味,看业务逻辑代码:前端:入门简单先易后难,能看到自己做出来的展示界面,有成就感. W ...

  8. Springboot + Spring Security 实现前后端分离登录认证及权限控制

    Spring Security简介 Spring Security 是 Spring 家族中的一个安全管理框架,实际上,在 Spring Boot 出现之前,Spring Security 就已经发展 ...

  9. Spring Web Flow 2中的流管理持久性

    Spring Web Flow是一个创新的Java™Web框架,它扩展了Spring MVC技术. 使用Spring Web Flow进行应用程序开发是围绕用例定义的,这些用例被定义为Web流. 根据 ...

最新文章

  1. IIS5.1错误,启动时WEB服务提示:服务器没有及时响应启动或控制请求 之终极解决方案。...
  2. 五、线程管理————GCD
  3. 【渝粤教育】国家开放大学2018年春季 0579-22T电路及磁路(2)(一) 参考试题
  4. 个人博客 V0.0.3 版本 ...
  5. 容器编排技术 -- Kubernetes是什么?
  6. 使用Linq作为rdlc报表的数据源
  7. android camera无预览拍照 后台拍照
  8. 数据结构c语言作业答案,数据结构C语言版第2版习题答案解析严蔚敏
  9. 信捷XC系列PLC编程软件安装方法
  10. 论文阅读 decaNLP -- The Natural Language Decathlon: Multitask Leaning as Question Answering
  11. 当你爸妈吐槽你的微信头像时,你该如何反击?
  12. diagram怎么记忆_怎样记英语单词本子单词记忆法原则让每个学生真正的
  13. 机器人硬汉 聆听_第268章 百拳机器人
  14. 简历模板...自行下载
  15. 如何屏蔽百度网盟广告
  16. 解决 E45: 'readonly' option is set (add ! to override)
  17. 神经网络(Neural Networks)简介
  18. 论文排版中MathType的使用(论文投稿必备)
  19. GO语言-自定义error
  20. 知乎大佬图文并茂的epoll讲解,看不懂的去砍他

热门文章

  1. JavaFX官方教程(六)之带有JavaFX CSS的花式表单
  2. eclipse安装、使用hibernate插件方法
  3. 阿里巴巴对Java编程【Mysql】的规约
  4. Shell入门(九)之字符串比较
  5. MyBatisPlus分页
  6. Zull路由网关---SpringCloud
  7. java文件输入与输出_java文件输入和输出
  8. java 连接 sql2005,java与sql server2005 连接有关问题
  9. mysql级联复制转换成一主两从_一主两从转级联复制
  10. HDU1231(最大连续子序列)