Webflux函数式编程模型以及WebClient使用
(1)在使用函数式编程模型操作的时候,需要自己初始化服务器
(2)基于函数式编程模型,有两个核心接口:RouterFunction(实现路由功能,请求转发给对应handler)和HandlerFunction(处理请求生成响应的函数)。核心任务定义两个函数式接口的实现并且启动需要的服务器。
(3)SpringWebFlux请求和响应不再是ServletRequest和ServletResponse,而是ServerRequest和ServerResponse
目录结构
- 第一步 把注解编程模型工程复制一份
- 第二步 创建Handler(具体实现方法)
UserHandler.java
package com.example.webfluxdemo2.handler;
import com.example.webfluxdemo2.Entity.User;
import com.example.webfluxdemo2.Service.UserService;
import org.springframework.http.MediaType;
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 static org.springframework.web.reactive.function.BodyInserters.fromObject;
public class UserHandler {
private final UserService userService;
public UserHandler(UserService userService){
this.userService=userService;
}
// 根据ID进行查询
public Mono<ServerResponse> getUserById(ServerRequest request){
// 获取ID值
int userId=Integer.valueOf(request.pathVariable("id"));
// 构建一个空值处理
Mono<ServerResponse> notFound=ServerResponse.notFound().build();
// 调用service方法得到数据
Mono<User> user = this.userService.getUserById(userId);
// 将mono对象转换成ServerResponse流的形式进行返回
// 使用Reactor操作符flatMap,可以使一个对象变成流,多个流合并成一个大流进行返回。
return
user.flatMap(person->ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(person)))
.switchIfEmpty(notFound); //如果为空就返回notFound对象
}
// 查询所有
public Mono<ServerResponse> getAllUser(ServerRequest request){
Flux<User> allUser = userService.getAllUser();
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(allUser,User.class);
}
// 添加
public Mono<ServerResponse> addUser(ServerRequest request){
// 得到user对象
Mono<User> userMono = request.bodyToMono(User.class); //User类型的对象
return ServerResponse.ok().build(userService.addUserInfo(userMono));
}
}
- 第三步初始化服务器,编写路由
Server.java
package com.example.webfluxdemo2;
import com.example.webfluxdemo2.Service.UserService;
import com.example.webfluxdemo2.Service.UserServiceimpl;
import com.example.webfluxdemo2.handler.UserHandler;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.netty.http.server.HttpServer;
import java.io.IOException;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler;
public class Server {
//3 最终调用
public static void main(String[] args) throws Exception {
Server server=new Server();
server.creatReactorServer();
System.out.println("enter to exit");
System.in.read();
}
// 1 创建路由
public RouterFunction<ServerResponse> routerFunction(){
// 创建handler对象
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::getAllUser);
}
// 2创建服务器完成适配
public void creatReactorServer(){
//路由和handler适配
RouterFunction<ServerResponse> route = routerFunction();
HttpHandler httpHandler = toHttpHandler(route);
ReactorHttpHandlerAdapter adapter=new ReactorHttpHandlerAdapter(httpHandler);
//创建服务器
HttpServer httpServer=HttpServer.create();
//进行构建
httpServer.handle(adapter).bindNow();
}
}
- 运行效果
WebClient使用
Client.java
package com.example.webfluxdemo2;
import com.example.webfluxdemo2.Entity.User;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
public class Client {
public static void main(String[] args) {
//调用服务器地址
WebClient webClient = WebClient.create("http://127.0.0.1:50641");
//根据Id进行查询
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();
//blockFirst类似于订阅的操作,不订阅没法显示
//map将一个元素转换为一个新元素
}
}
运行效果