如何在 Spring 中通过 HTTP 响应传递和处理异常?

How to pass and handle Exceptions through HTTP responses in Spring?

我的 Spring 项目 运行 在不同的端口上有一个客户端和服务器模块。客户端模块通过 RestTemplate 向服务器发出 POST 请求。服务器模块抛出带有自定义错误消息的自定义异常。目前,在我的项目中,服务器有一个 RestControllerAdvice Class 来处理如下异常:

@RestControllerAdvice
public class AppRestControllerAdvice {
    @ExceptionHandler(ApiException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public MessageData handle(ApiException e) {
        MessageData data = new MessageData();
        data.setMessage(e.getMessage());
        return data;
    }
}

在客户端,以下方法捕获来自服务器的响应。

@RestControllerAdvice
public class AppRestControllerAdvice {
    @ExceptionHandler(ApiException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public MessageData handle(ApiException e) {
        MessageData data = new MessageData();
        data.setMessage(e.getMessage());
        return data;
    }

    @ExceptionHandler(Throwable.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public MessageData handle(Throwable e) {
        MessageData data = new MessageData();
        data.setMessage("UNKNOWN ERROR- " + e.getMessage());
        e.printStackTrace();
        return data;
    }
}

每当服务器抛出异常时,这是我在客户端收到的内容

{
  "message": "UNKNOWN ERROR- org.springframework.web.client.HttpClientErrorException: 400 Bad Request"
}

我的问题是,如何检索源自服务器的自定义异常消息?

还有,为什么客户端的正确 RestControllerAdvice 模块没有检测到错误? (INTERNAL_SERVER_ERROR 方法捕获错误,而不是 BAD_REQUEST 方法。)

My question is, how do I retrieve the Custom Exception message that originated on the Server?

要检索原始异常消息,您必须使用能够提取该信息的专用 ResponseErrorHandler,而不是使用默认消息(DefaultResponseErrorHandler - 我假设您使用它是因为您收到的消息 - org.springframework.web.client.HttpClientErrorException: 400 Bad Request).

创建:

public class CustomerResponseErrorHandler extends DefaultResponseErrorHandler {

    @Override
    public void handleError(ClientHttpResponse httpResponse) throws IOException {

        // here you have access to the response's body which potentially contains the exception message you are interested in  
        // simply extract it if possible and throw an exception with that message
        // in other case you can simply call `super.handlerError()` - do whatever suits you

    }
}

然后将其与您的 RestTemplate:

一起使用
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
          .errorHandler(new CustomerResponseErrorHandler())
          .build();
    }

}

Also, why isn't the correct RestControllerAdvice module on the Client side picking up the error? (The INTERNAL_SERVER_ERROR method catches the error instead of the BAD_REQUEST method.)

执行了正确的方法 - 您的 RestTemplate 目前正在抛出 HttpClientErrorException 而不是 ApiException。不过是Throwable