前言
[TOC]
一般来说,http请求的状态码,只是表明请求是否有问题,不能表明错再哪里了.比如用户只是业务问题,需要给个警告,但是http的状态码不能说明业务问题.于是很多系统都采用了类似如下的响应体
{
code: xxx,
msg: xxx,
data: xxxxxx
}
我也是需要这样的响应体.但是webflux需要你返回Mono对象或者Flux对象.才符合响应式开发的必要条件.
所以常规的直接把内容放到响应体中是不可取的.需要再封装.
解决方案
第一种(亲测问题巨多)
- 在webflux处理响应信息的时候,通过切面替换webflux即将要返回的响应内容,包装一个响应体.
-
优点
- 侵入性小
-
缺点
-
接受类型众多需要适配
- 本代码中只适配了2种常规类型
- 一旦用户返回Flux或者其他内容直接报错了.
- 问题巨多不一一描述了
-
第二种(相对完美的方案)
- 依靠响应体的方法,把响应内容再加工
-
优点
- 不影响webflux源码
- 基本没有任何问题
- 只需要修改响应体代码
-
缺点
- 侵入性(一般响应体也是这样,所以也不太算缺点)
第一个方案
参考:https://blog.csdn.net/xuguangyuansh/article/details/100288216
他的是kotlin版的.
所以我写了一个java sringboot版的.
// 响应体
@Data
@ToString
public class ResponseInfo<T> implements Serializable {
String msg;
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;
}
}
// 切面bean,统一替换.
/**
* webflux响应信息统一切换
*/
@Aspect
@Component
@ConditionalOnClass(name = {"org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler"})
public class ResponseBodyResultHandlerAspect {
@SneakyThrows
@Around(value = "execution(* org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler.handleResult(..)) && args(exchange, result)", argNames = "point,exchange,result")
public Object handleResult(ProceedingJoinPoint point, ServerWebExchange exchange, HandlerResult result) {
final Mono responseMono = ((Mono) result.getReturnValue()).map(responseValue -> responseValue instanceof ResponseInfo ? responseValue : ResponseInfo.ok(responseValue));
return point.proceed(Arrays.asList(
exchange,
new HandlerResult(result.getHandler(), responseMono, result.getReturnTypeSource())
).toArray());
}
}
// 控制层
@RestController
@RequestMapping("/test")
public class UserController {
@GetMapping("/oop")
public Mono getStr() {
// 模拟获取数据的Mono序列
final Mono<String> data = Mono.just("test");
return data;
}
}
第二个方案
自己写的.
// 装饰Mono的响应体工具类,自己修改一下自己的响应体对象也可以
@Data
@ToString
public class ResponseInfo<T> implements Serializable {
String msg;
Integer code;
Object data;
public static <T> Mono<ResponseInfo<T>> ok (Mono<T> monoBody) {
return responseBodyCreate(monoBody,0,null);
}
public static <T> Mono<ResponseInfo<T>> ok (Mono<T> monoBody, String msg) {
return responseBodyCreate(monoBody,0,msg);
}
public static <T> Mono<ResponseInfo<T>> ok (Mono<T> monoBody, int code, String msg) {
return responseBodyCreate(monoBody,code,msg);
}
public static <T> Mono<ResponseInfo<T>> failed (Mono<T> monoBody) {
return responseBodyCreate(monoBody,0,null);
}
public static <T> Mono<ResponseInfo<T>> failed (Mono<T> monoBody, String msg) {
return responseBodyCreate(monoBody,0,msg);
}
public static <T> Mono<ResponseInfo<T>> failed (Mono<T> monoBody, int code, String msg) {
return responseBodyCreate(monoBody,code,msg);
}
private static <T> Mono<ResponseInfo<T>> responseBodyCreate(Mono<T> monoData, int code, String msg) {
return monoData.map(data-> {
final ResponseInfo<T> responseInfo = new ResponseInfo<>();
responseInfo.setCode(code);
responseInfo.setData(data);
responseInfo.setMsg(msg);
return responseInfo;
});
}
}
// 控制层
@RestController
@RequestMapping("/test")
public class UserController {
@GetMapping("/oop")
public Mono getStr() {
// 模拟获取数据
final Mono<String> data = Mono.just("test");
return ResponseInfo.ok(data);
// 简写
// return ResponseInfo.ok(Mono.just("test"));
}
}
结束语
约束语?不存在的,如果有帮助就请给个赞把.感谢!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。