我有两个微服务,让我们说一个前端和后端,对于前端,我使用 WebFlux 并使用 feign 客户端调用后端服务,如下面的代码示例所示,虽然下面的代码示例有效,但我想要使用 Function 的通用异常处理程序并提供给 onErrorMap
@RestController
@Slf4j
public class MyFrentEndService {
@Autowired
private MyBackEndService client;
@PostMapping(value="/hello", consumes="application/json")
public Mono<Void> sayHello(@Valid String msg) {
log.info("Message is {}", msg);
return Mono.create(sink-> {
try {
client.hello(msg);
}catch (FeignException e) {
System.out.println(e.status());
HttpStatus status = e.status() ==0 ? HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
String message = e.getMessage();
sink.error(new ResponseStatusException(status, message));
}
sink.success();
});
}
}
尝试使用onErrorMap
,但出现编译错误,请使用 Mono 而不是 Mono<Void>
@RestController
@Slf4j
public class MyFrentEndService {
@Autowired
private MyBackEndService client;
@PostMapping(value="/hello", consumes="application/json")
public Mono<Void> sayHello(@Valid String msg) {
log.info("Message is {}", msg);
return Mono.fromSupplier(() -> {
client.hello(msg);
return null;
}).onErrorMap(e->{
HttpStatus status = e.status() ==0 } HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
String message = e.getMessage();
return new ResponseStatusException(status, message);
});
}
}
如何使用onErrorMap
?
最佳答案
此错误与运算符onErrorMap
无关。此代码无法编译,因为编译器无法将 Mono.fromSupplier
方法返回的泛型类型推断为 Void
- 您在提供的函数上返回 null。
应通过执行以下操作来纠正此问题:
@PostMapping(value="/hello", consumes="application/json")
public Mono<Void> sayHello(@Valid String msg) {
log.info("Message is {}", msg);
return Mono.<Void>fromSupplier(() -> {
client.hello(msg);
return null;
}).onErrorMap(e->{
HttpStatus status = e.status() ==0 ? HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
String message = e.getMessage();
return new ResponseStatusException(status, message);
});
}
我认为执行以下操作更为惯用:
@PostMapping(value="/hello", consumes="application/json")
public Mono<Void> sayHello(@Valid String msg) {
log.info("Message is {}", msg);
return Mono.fromRunnable(() -> {
client.hello(msg);
})
.then()
.onErrorMap(e->{
HttpStatus status = e.status() ==0 ? HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
String message = e.getMessage();
return new ResponseStatusException(status, message);
});
}
最后,我建议不要在响应式(Reactive)管道内使用阻塞调用,除非确实有必要。 (首选 WebClient 或其他非阻塞 HTTP 客户端,而不是阻塞客户端作为 feign)。
关于spring-boot - 在 Mono<Void> 的 WebFlux 中使用 onErrorMap 时发生映射错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55934420/