做像淘宝网的网站,怎么做网站前台,成都专业网站建设,最近的国际新闻热点spring flux在上一篇文章中#xff0c;我介绍了Spring Web-Flux的基础知识#xff0c;它表示Spring框架的Web层中的响应式支持。 我已经展示了使用Spring Data Cassandra并在Spring Web Layers中使用传统注释支持的端到端示例#xff0c; 大致如下#xff1a; ...
import… 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 MonoHotel get(PathVariable(id) UUID uuid) {...}GetMapping(path /startingwith/{letter})public FluxHotelByLetter findHotelsWithLetter(PathVariable(letter) String letter) {...}} 除了返回类型外这看起来像传统的Spring Web注释这些端点不是返回域类型而是通过Reactor -core中的Mono和Flux的实现返回Publisher类型而Spring-Web则将内容流回。 在本文中我将介绍一种不同的公开端点的方法-使用功能样式而不是注释样式。 让我承认对于我了解公开Web端点的功能样式的理解我发现Baeldung的文章和Rossen Stoyanchev的文章非常宝贵。 将注释映射到路线 让我从一些基于注释的端点开始一个用于检索实体另一个用于保存实体 GetMapping(path /{id})
public MonoHotel get(PathVariable(id) UUID uuid) {return this.hotelService.findOne(uuid);
}PostMapping
public MonoResponseEntityHotel 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 MonoServerResponse get(ServerRequest request) {UUID uuid UUID.fromString(request.pathVariable(id));MonoServerResponse notFound ServerResponse.notFound().build();return this.hotelService.findOne(uuid).flatMap(hotel - ServerResponse.ok().body(Mono.just(hotel), Hotel.class)).switchIfEmpty(notFound);}public MonoServerResponse save(ServerRequest serverRequest) {MonoHotel 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.htmlspring flux