spring-boot - 使用 Spring boot + WebFlux 进行全局错误处理
问题描述
在 Spring Boot Rest Controller 中使用响应式编程时,我们如何全局处理异常?
我认为这@ControllerAdvice
行不通,因为我已经尝试过了,但没有成功。
我的另一个尝试目前是这个选项,使用自定义属性:
@Component
public class OsvcErrorAttributes extends DefaultErrorAttributes {
public OsvcErrorAttributes() {
super(true);
}
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
return assembleError(request);
}
private Map<String, Object> assembleError(ServerRequest request) {
ServerException serverException = (ServerException)getError(request);
Map<String, Object> errorAttributes = new HashMap<>();
errorAttributes.put("message", serverException.getMessage());
errorAttributes.put("errors", serverException.getErrorMap());
return errorAttributes;
}
}
和 WebExceptionHandler 像这样:
@Component
@Order(-2)
public class OsvcErrorHandler extends AbstractErrorWebExceptionHandler {
public OsvcErrorHandler(ErrorAttributes errorAttributes,
ResourceProperties resourceProperties,
ApplicationContext applicationContext) {
super(errorAttributes, resourceProperties, applicationContext);
// TODO: 25.06.2019 temporary workaround
ServerCodecConfigurer serverCodecConfigurer = new DefaultServerCodecConfigurer();
setMessageWriters(serverCodecConfigurer.getWriters());
setMessageReaders(serverCodecConfigurer.getReaders());
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(ServerRequest serverRequest) {
final Map<String, Object> errorAttributes = getErrorAttributes(serverRequest, true);
return ServerResponse.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(errorAttributes));
}
}
产生错误的代码:
@Data
@Service
public class ContactService {
private final ContactRepository contactRepository;
public Mono<Business> saveNewContact(Business business) {
return contactRepository.save(business)
.onErrorMap(throwable ->
ServerException.create(throwable.getMessage())
.persistError("ico", business.getIco(), "ICO is probably duplicate"));
}
}
问题是这也不起作用。我确实遵循了本教程,但我看不出我是否有什么问题。
解决方案
您只需像这样在全局错误处理程序构造函数中使用 ServerCodecConfigurer 注入。
public OsvcErrorHandler(GlobalErrorAttributes errorAttributes, ApplicationContext applicationContext,
ServerCodecConfigurer serverCodecConfigurer) {
super(errorAttributes, new ResourceProperties(), applicationContext);
super.setMessageWriters(serverCodecConfigurer.getWriters());
super.setMessageReaders(serverCodecConfigurer.getReaders());
}
请在 git存储库中找到代码示例。
推荐阅读
- python-3.x - list1 == list2.reverse() 如何在 python 中执行?
- javascript - 为什么这个 Skulpt Python 编辑器没有按预期工作?
- php - paypal api curl退款出现错误AUTHENTICATION_FAILURE
- java - Firestore 中的文档在添加或设置后立即被删除
- wolfram-mathematica - 在 Mathematica 中通过引用传递列表元素
- sql - 加入内部和外部子查询
- c++ - C++ 和 Rust 之间的共享内存
- python - 如何用 discord bot python 警告某人
- java - 如何从字节 [] 打印十六进制?
- amazon-web-services - Amazon Linux 2 上的 Elastic Beanstalk、Django、Docker 平台 - 在 postdeploy 钩子不工作中运行 docker-compose exec