在 SpringBoot 中,我们通常会对项目中封装一个消息返回对象。使用统一的编码,这个返现消息体是在 HTTP 的状态码上又包装了一层。如下所示:
{
code:996,
msg:"www.xttblog.com",
data:[{url:"www.xttblog.com",name:""}]
}
今天也有一个网友,在 WebFlux 群里问我,针对 Flux 和 Mono 如何封装这种消息对象?下面说一下我的做法。
先封装一个返回前端的消息体,代码如下所示:
public class ResponseInfo<T> implements Serializable {
private String msg;
private Integer code;
Object data;
public static <T> ResponseInfo<T> ok (T monoBody) {
final ResponseInfo<T> responseInfo = new ResponseInfo<>();
responseInfo.setCode(0);
responseInfo.setData(monoBody);
responseInfo.setMsg("ok");
return responseInfo;
}
// 省略其他 get/set 和 error 等
}
然后在返回 Mono 的地方进行包装。
// 控制层
@RestController
@RequestMapping("/test")
public class UserController {
@GetMapping("/oop")
public Mono getXttblog() {
// 模拟获取数据
final Mono<String> data = Mono.just("微信号:codedq");
//return ResponseInfo.ok(data);
// 简写
return Mono.just(ResponseInfo.ok(data));
}
}
Mono 返回数据封装起来很简单,但是在返回 Flux 的地方就不好封装了。因为一个 Flux 对象代表一个包含 0 个或多个(0..N)元素的响应式序列,而一个 Mono 对象代表一个包含 0 或一个(0..1)元素的结果。
通常我们的 Repository 返回的都是 Flux 数据流。通过 Controller 返回给前端的数据转换成 JOSN 基本上就是一个数组 […]。
public Flux<Project> findAllPrj() {
return projectRepository.findAll();
}
如果是 Flux<ResponseInfo>,那就是数组中每个对象都带有 code,msg,data 信息。
这个时候,我们应该要想到 Flux 的 flatMap 方法。下面看一个 Flux.flatMap 方法的转换例子。
public Mono<ServerResponse> getDeviceTypes(){
return deviceService.findDeviceTypes()
.flatMap(devices -> {
ResponseInfo r = new ResponseInfo();
r.setMessage("Test");
r.setCode("200");
r.setStatus(200);
r.setData(devices);
return ok().body(Mono.just(r), ResponseInfo.class);
});
}
以上,希望能够帮助到更多人。更多关于 WebFlux 的使用技巧,请阅读这些文章:《Spring WebFlux 教程》。
: » WebFlux之Flux、Mono自定义统一返回消息
原创文章,作者:wdmbts,如若转载,请注明出处:https://blog.ytso.com/tech/java/252199.html