spring flux

在上一篇文章中,我介绍了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 flux

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

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

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

  2. okta-spring_通过Okta的单点登录保护Spring Boot Web App的安全

    okta-spring "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多 ...

  3. 通过Okta的单点登录保护Spring Boot Web App的安全

    "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. 您可以使 ...

  4. spring 5.x(1)-----Spring Framework 5.x中的新功能

    Spring Framework 5.x中有什么新功能 5.1版中的新功能 一般核心修订 基础设施: 在类路径和模块路径上对JDK 11的无警告支持. 支持Graal原生图像约束(反射,参数名称). ...

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

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

  6. Java Web和Java后端开发的学习路线

    基础:比如计算机系统.算法.编译原理等等 Web开发: 主要是Web开发相关的内容,包括HTML/CSS/JS(前端页面).Servlet/JSP(J2EE)以及Mysql(数据库)相关的知识.它们的 ...

  7. Java Web和Java后端学习之路

    摘要: 每个阶段要学习的内容甚至是一些书籍.针对Java Web和Java后端开发 java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是我你是如何学习Java的 ...

  8. 基于spring security实现vue2前后端分离的双token刷新机制(完整代码详解,含金量拉满!)

    目录 一.前言: 核心功能概要: 通过加密算法创建一个用户: 二.后端 代码详解: 1.代码整体结构: 2.所需依赖: 3.UserDetailServiceImpl拦截用户登陆: 4.所需工具类 4 ...

  9. Spring与Web环境集成

    1. Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(sprin ...

最新文章

  1. 计算机组成原理考研重点
  2. 什么是 Design System
  3. python项目-这4个Python实战项目,让你瞬间读懂Python!
  4. SpringBoot中Tomcat配置(学习SpringBoot实战)
  5. c cuda 指定gpu_《CUDA C编程权威指南》——1.3 用GPU输出Hello World-阿里云开发者社区...
  6. linux命令编译C语言程序
  7. LeetCode 327. 区间和的个数(multiset二分查找/归并排序)
  8. centos7.9使用rpm安装Jenkins_亲测成功---持续集成部署Jenkins工作笔记0022
  9. 对象 'dbo.xxx' 不存在,或对此操作无效。为表创建触发器,为什么提示对象不存在?
  10. Linux下如何关闭命令行正在执行的程序或命令
  11. JSONView下载安装
  12. java地理位置的获取_Java 根据 IP 获取地理位置
  13. jde多目标_CVPR 2020多目标跟踪算法的JDE训练,CVPR2020
  14. 关于 NM_CONTROLLED和Network Manager
  15. zmq pub/sub使用详解
  16. 用Python快速分析和预测股票价格
  17. 企业微信小程序_获取准确定位的方法及解决定位不准确的问题
  18. JavaSE进阶26 - IO流概述、字节流、字符流、转换流、缓冲流
  19. rancher/ui 路由资源对应表
  20. 头歌MySQL数据库实训答案2022

热门文章

  1. P7887-「MCOI-06」Existence of Truth【构造】
  2. jzoj6312-Lottery【dp,前缀和】
  3. 欢乐纪中A组赛【2019.8.18】
  4. Ch4201-楼兰图腾【树状数组】
  5. 【dfs】【模拟】【树】I Like Matrix Forever!
  6. consul的安装搭建
  7. 内存模型是怎么解决缓存一致性的
  8. JavaFX官方教程(五)之在JavaFX中创建表单
  9. 线上防雪崩利器——熔断器设计原理与实现
  10. 彻底理解HashMap的元素插入原理