当前位置: 首页 > 知识库问答 >
问题:

Spring WebClient-如何在HTTP错误(4xx,5xx)的情况下访问响应体?

毋炳
2023-03-14

我想将我的异常从我的“数据库”REST API重新抛出到我的“后端”REST API,但我丢失了原始异常的消息

这是我通过Postman从我的“数据库”REST API中得到的:

{
    "timestamp": "2020-03-18T15:19:14.273+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "I'm DatabaseException (0)",
    "path": "/database/api/vehicle/test/0"
}

这部分没问题。

这是我通过Postman从我的“后端”REST API得到的:

{
    "timestamp": "2020-03-18T15:22:12.801+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "400 BAD_REQUEST \"\"; nested exception is org.springframework.web.reactive.function.client.WebClientResponseException$BadRequest: 400 Bad Request from GET http://localhost:8090/database/api/vehicle/test/0",
    "path": "/backend/api/vehicle/test/0"
}

如您所见,原来的“message”字段丢失了。

我使用:

  • Spring boot 2.2.5.发布
  • spring-boot-starter-web
  • spring-boot-starter-webflux

这是后端:

    @GetMapping(path = "/test/{id}")
    public Mono<Integer> test(@PathVariable String id) {
        return vehicleService.test(id);
    }

使用VehicleService.Test:

    public Mono<Integer> test(String id) {
        return WebClient
            .create("http://localhost:8090/database/api")
            .get()
            .uri("/vehicle/test/{id}", id)
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(Integer.class);
    }

这是数据库:

    @GetMapping(path = "/test/{id}")
    public Mono<Integer> test(@PathVariable String id) throws Exception {

        if (id.equals("0")) {
            throw new DatabaseException("I'm DatabaseException (0)");
        }

        return Mono.just(Integer.valueOf(2));
    }

和DatabaseException:

public class DatabaseException extends ResponseStatusException {

    private static final long serialVersionUID = 1L;

    public DatabaseException(String message) {
        super(HttpStatus.BAD_REQUEST, message);

    }
}

似乎我的后端转换了响应,在互联网上找不到任何答案。

共有1个答案

顾池暝
2023-03-14

可以使用exchange,而不是webclientretrieve,它允许您处理错误并传播带有从服务响应检索到的消息的自定义异常。

private void execute()
{
    WebClient webClient = WebClient.create();

    webClient.get()
             .uri("http://localhost:8089")
             .exchangeToMono(this::handleResponse)
             .doOnNext(System.out::println)
             .block();  // not required, just for testing purposes
}

private Mono<Response> handleResponse(ClientResponse clientResponse)
{
    if (clientResponse.statusCode().isError())
    {
        return clientResponse.bodyToMono(Response.class)
                             .flatMap(response -> Mono.error(new RuntimeException(response.message)));
    }

    return clientResponse.bodyToMono(Response.class);
}

private static class Response
{
    private String message;

    public Response()
    {
    }

    public String getMessage()
    {
        return message;
    }

    public void setMessage(String message)
    {
        this.message = message;
    }

    @Override
    public String toString()
    {
        return "Response{" +
                "message='" + message + '\'' +
                '}';
    }
}
 类似资料:
  • 有人能告诉我如何处理CodeIgniter中的4xx和5xx错误吗?我必须为每个案例向用户显示不同的模板。目前我只能用show_404()函数处理404错误。请告诉我如何查找和处理其他错误,例如: 400错误请求 401需要授权 402需要付款(尚未使用) 403禁止 405方法不允许 406不可接受(编码) 407需要代理身份验证 408请求超时 409冲突请求 410消失 411需要内容长度

  • 我有一个rest web服务。如果抛出任何异常,web服务将返回http 500错误。但我不想发送这个带有异常堆栈跟踪的错误响应。我只想发送错误代码和错误消息。我没有做到这一点。我怎么能这么做? 我已经尝试过@ControllerAdvice和@ExceptionHandler注释,但我做不到。当我使用@ResponseStatus注释时,总是发送静态“reason”值。如何设置此值?谢谢你的帮助

  • 我正在使用Tomcat 6(但同样适用于Tomcat 7)。假设我的 包含以下定义: 假设我现在从其他servlet/JSP返回HTTP 401: 如何访问中的HTTP响应文本("这是一条消息")?Tomcat这样做的方式,当它显示这样的错误页面时 是通过使用 Valve ()。我也需要编写吗? 编辑:下面接受的答案正是我一直在寻找的,这个问题的假设重复没有提到相同的解决方案。

  • 我试图用一个网络客户端来替换现有的客户机代码。因此,大多数调用都需要阻塞,这样应用程序的主要部分就不需要更改。当谈到错误处理时,这会带来一些问题。必须涵盖以下几种情况: 在成功的情况下,响应包含A类型的JSON对象 在错误情况下(HTTP状态4xx或5xx)响应可能包含B类型的JSON对象 在某些具有响应状态404的请求上,我需要返回一个与成功响应类型匹配的空 为了产生正确的错误(

  • 我是Spring Boot framework的WebClient的新手。我如何仅记录4xx/5xx,其错误主体仅在错误上,但如果成功,则将作为