| 1、在使用函数式编程模型操作时候,需要自己初始化服务器 |
| 2、基于函数式编程模型时候,有两个核心接口:RouterFunction(实现路由功能,请求转发给对应的 handler)和 HandlerFunction(处理请求生成响应的函数)。核心任务定义两个函数 |
| 式接口的实现并且启动需要的服务器 |
| 3、SpringWebflux 请 求 和 响 应 不 再 是 ServletRequest 和 ServletResponse ,而是ServerRequest 和 ServerResponse |
| <dependencies> |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-webflux</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-test</artifactId> |
| <scope>test</scope> |
| </dependency> |
| </dependencies> |
| public class User { |
| |
| private String name; |
| |
| private String gender; |
| |
| private Integer age; |
| |
| public void setName(String name) { |
| this.name = name; |
| } |
| |
| public void setGender(String gender) { |
| this.gender = gender; |
| } |
| |
| public void setAge(Integer age) { |
| this.age = age; |
| } |
| |
| public String getName() { |
| return name; |
| } |
| |
| public String getGender() { |
| return gender; |
| } |
| |
| public Integer getAge() { |
| return age; |
| } |
| |
| public User() { |
| } |
| |
| public User(String name, String gender, Integer age) { |
| this.name = name; |
| this.gender = gender; |
| this.age = age; |
| } |
| |
| } |
| public interface UserService { |
| |
| |
| Mono<User> getUserById(int id); |
| |
| |
| Flux<User> getAllUser(); |
| |
| |
| Mono<Void> saveUserInfo(Mono<User> user); |
| |
| } |
| @Repository |
| public class UserServiceImpl implements UserService { |
| |
| |
| private final Map<Integer,User> users = new HashMap<>(); |
| |
| public UserServiceImpl() { |
| this.users.put(1,new User("lucy","nan",20)); |
| this.users.put(2,new User("mary","nv",30)); |
| this.users.put(3,new User("jack","nv",50)); |
| } |
| |
| |
| @Override |
| public Mono<User> getUserById(int id) { |
| return Mono.justOrEmpty(this.users.get(id)); |
| } |
| |
| |
| @Override |
| public Flux<User> getAllUser() { |
| return Flux.fromIterable(this.users.values()); |
| } |
| |
| |
| @Override |
| public Mono<Void> saveUserInfo(Mono<User> userMono) { |
| return userMono.doOnNext(person -> { |
| |
| int id = users.size()+1; |
| users.put(id,person); |
| }).thenEmpty(Mono.empty()); |
| } |
| |
| } |
| public class UserHandler { |
| |
| private final UserService userService; |
| |
| |
| public UserHandler(UserService userService) { |
| this.userService = userService; |
| } |
| |
| |
| public Mono<ServerResponse> getUserById(ServerRequest request) { |
| |
| int userId = Integer.valueOf(request.pathVariable("id")); |
| |
| Mono<ServerResponse> notFound = ServerResponse.notFound().build(); |
| |
| Mono<User> userMono = this.userService.getUserById(userId); |
| |
| |
| return userMono.flatMap(person -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON) |
| .body(fromObject(person))) |
| .switchIfEmpty(notFound); |
| } |
| |
| |
| public Mono<ServerResponse> getAllUsers(ServerRequest request) { |
| |
| Flux<User> users = this.userService.getAllUser(); |
| return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(users,User.class); |
| } |
| |
| |
| public Mono<ServerResponse> saveUser(ServerRequest request) { |
| |
| Mono<User> userMono = request.bodyToMono(User.class); |
| return ServerResponse.ok().build(this.userService.saveUserInfo(userMono)); |
| } |
| |
| } |
| public class Server { |
| |
| public static void main(String[] args) throws Exception{ |
| Server server = new Server(); |
| server.createReactorServer(); |
| System.out.println("enter to exit"); |
| System.in.read(); |
| } |
| |
| |
| public RouterFunction<ServerResponse> routingFunction() { |
| |
| UserService userService = new UserServiceImpl(); |
| UserHandler handler = new UserHandler(userService); |
| |
| return RouterFunctions.route( |
| |
| GET("/users/{id}").and(accept(APPLICATION_JSON)),handler::getUserById) |
| .andRoute(GET("/users").and(accept(APPLICATION_JSON)),handler::getAllUsers); |
| } |
| |
| |
| public void createReactorServer() { |
| |
| RouterFunction<ServerResponse> route = routingFunction(); |
| HttpHandler httpHandler = toHttpHandler(route); |
| ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler); |
| |
| HttpServer httpServer = HttpServer.create(); |
| httpServer.handle(adapter).bindNow(); |
| } |
| |
| } |
-
启动测试


-
编写客户端
| public class Client { |
| |
| public static void main(String[] args) { |
| |
| WebClient webClient = WebClient.create("http://127.0.0.1:61824"); |
| |
| |
| String id = "1"; |
| |
| User userresult = webClient.get().uri("/users/{id}", id) |
| .accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(User.class) |
| .block(); |
| System.out.println(userresult.getName()); |
| |
| |
| Flux<User> results = webClient.get().uri("/users") |
| .accept(MediaType.APPLICATION_JSON).retrieve().bodyToFlux(User.class); |
| results.map(stu -> stu.getName()) |
| .buffer().doOnNext(System.out::println).blockFirst(); |
| } |
| |
| } |
| 16:46:40.743 [main] DEBUG org.springframework.web.reactive.function.client.ExchangeFunctions - [2f16c6b3] HTTP GET http: |
| 16:46:41.137 [main] DEBUG org.springframework.web.reactive.function.client.ExchangeFunctions - [2484f433] HTTP GET http: |
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术