spring flux_Spring Web-Flux – Cassandra后端的功能样式
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后端的功能样式相关推荐
- Spring Web-Flux – Cassandra后端的功能样式
在上一篇文章中,我介绍了Spring Web-Flux的基础知识,它表示Spring框架的Web层中的响应式支持. 我已经展示了使用Spring Data Cassandra并在Spring Web ...
- okta-spring_通过Okta的单点登录保护Spring Boot Web App的安全
okta-spring "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多 ...
- 通过Okta的单点登录保护Spring Boot Web App的安全
"我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. 您可以使 ...
- spring 5.x(1)-----Spring Framework 5.x中的新功能
Spring Framework 5.x中有什么新功能 5.1版中的新功能 一般核心修订 基础设施: 在类路径和模块路径上对JDK 11的无警告支持. 支持Graal原生图像约束(反射,参数名称). ...
- Web前端和后端的区别是什么?如何区分?
Web前端和后端的区别是什么?如何区分?从前端和后端两者工作内容和负责项目是完全不同.后端:入门难深入更难,枯燥乏味,看业务逻辑代码:前端:入门简单先易后难,能看到自己做出来的展示界面,有成就感. W ...
- Java Web和Java后端开发的学习路线
基础:比如计算机系统.算法.编译原理等等 Web开发: 主要是Web开发相关的内容,包括HTML/CSS/JS(前端页面).Servlet/JSP(J2EE)以及Mysql(数据库)相关的知识.它们的 ...
- Java Web和Java后端学习之路
摘要: 每个阶段要学习的内容甚至是一些书籍.针对Java Web和Java后端开发 java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是我你是如何学习Java的 ...
- 基于spring security实现vue2前后端分离的双token刷新机制(完整代码详解,含金量拉满!)
目录 一.前言: 核心功能概要: 通过加密算法创建一个用户: 二.后端 代码详解: 1.代码整体结构: 2.所需依赖: 3.UserDetailServiceImpl拦截用户登陆: 4.所需工具类 4 ...
- Spring与Web环境集成
1. Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(sprin ...
最新文章
- 计算机组成原理考研重点
- 什么是 Design System
- python项目-这4个Python实战项目,让你瞬间读懂Python!
- SpringBoot中Tomcat配置(学习SpringBoot实战)
- c cuda 指定gpu_《CUDA C编程权威指南》——1.3 用GPU输出Hello World-阿里云开发者社区...
- linux命令编译C语言程序
- LeetCode 327. 区间和的个数(multiset二分查找/归并排序)
- centos7.9使用rpm安装Jenkins_亲测成功---持续集成部署Jenkins工作笔记0022
- 对象 'dbo.xxx' 不存在,或对此操作无效。为表创建触发器,为什么提示对象不存在?
- Linux下如何关闭命令行正在执行的程序或命令
- JSONView下载安装
- java地理位置的获取_Java 根据 IP 获取地理位置
- jde多目标_CVPR 2020多目标跟踪算法的JDE训练,CVPR2020
- 关于 NM_CONTROLLED和Network Manager
- zmq pub/sub使用详解
- 用Python快速分析和预测股票价格
- 企业微信小程序_获取准确定位的方法及解决定位不准确的问题
- JavaSE进阶26 - IO流概述、字节流、字符流、转换流、缓冲流
- rancher/ui 路由资源对应表
- 头歌MySQL数据库实训答案2022