一、实现ErrorWebExceptionHandler
接口
import com.alibaba.fastjson.JSONObject;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufMono;
@Component
@Order(-1)
public class FilterExceptionHandler implements ErrorWebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.OK);
ResultVO resultVO = ResultVO.failMessageInSuccess(ex.getMessage()); // 自定义的返回对象
DataBuffer dataBuffer = response.bufferFactory()
.allocateBuffer().write(JSONObject.toJSONString(resultVO).getBytes());
//基于流形式
response.getHeaders().setContentType(MediaType.APPLICATION_STREAM_JSON);
return response.writeAndFlushWith(Mono.just(ByteBufMono.just(dataBuffer)));
}
}
二、在需要抛出异常的地方返回Mono.error(new Exception("错误消息"))
return Flux.just(1, 2, 3).collectList().flatMap(list -> {
if (list.size() <= 4) {
return Mono.error(new Exception("集合太小!"));
}
return Mono.just(list);
}).flatMap(r -> ok().body(fromValue(r)));
三、测试
postman发送请求,得到结果:
{
"code": "500",
"data": {},
"message": "集合太小!",
"success": false
}
纠正:
return Mono.error
之后,如果流后面还有其他操作,会继续执行,而不是中断流的执行。
如果需要中断流的执行,则需要throw
异常
@Test
public void testError() {
Flux.range(1, 6).map(n -> {
if (n == 5) {
// throw new RuntimeException("exception");
return Mono.error(new Exception("exception"));
}
System.out.println(n);
return Mono.just(n);
}).collectList().map(list -> {
System.out.println(list.size());
return Mono.just("");
}).subscribe(System.out::println);
}
Mono.error
结果:
1
2
3
4
6
6
MonoJust
可以看到,5现异常没有打印,但6会正常输出
throw
结果:
@Test
public void testError() {
Flux.range(1, 6).map(n -> {
if (n == 5) {
throw new RuntimeException("exception");
//return Mono.error(new Exception("exception"));
}
System.out.println(n);
return Mono.just(n);
}).collectList().map(list -> {
System.out.println(list.size());
return Mono.just("");
}).subscribe(System.out::println);
}
结果:
1
2
3
4
[ERROR] (main) Operator called default onErrorDropped - reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.RuntimeException: exception