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

返回单声道和流量误差总是返回500

容远
2023-03-14
package com.example.demo;

import javax.xml.ws.http.HTTPException;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import reactor.core.publisher.Mono;

@RestController
public class Controller {

@RequestMapping(
        path="/getExceptionMono",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<String> getException(){
        return Mono.error(new HTTPException(401));
    }
}
package com.example.demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;

@Component
public class ReactiveDemoConsumer implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        String url = "http://localhost:8080/getExceptionMono";
        WebClient.create(url)
            .get()
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(String.class)
            .subscribe(value -> System.err.println("Received String: " + value),
                        err -> System.err.println("Received error " + err));

    }
}
Received error org.springframework.web.reactive.function.client.WebClientResponseException$InternalServerError: 500 Internal Server Error from GET http://localhost:8080/getExceptionMono

我如何传递我的异常,以便使用者将看到我在单声道中传递的原始异常?希望我的问题很清楚,提前谢谢

共有1个答案

淳于飞鸾
2023-03-14

这不是从应用程序返回4xx响应的正确方式。在应用程序中引发的任何类型的异常都将由WebClientResponseException包装,并在客户端作为500内部服务器错误接收。

改变这种情况的一种方法是在控制器中使用异常处理程序,如下所示:

  @ExceptionHandler({UnsupportedMediaTypeException.class})
  public ResponseEntity<String> exceptionHandler(Exception ex) {
    return ResponseEntity.badRequest().body(ex.getMessage());
  }

另一种方法是在代码中使用全局异常处理程序:(这里Ex1类似于HTTPException)

@Component
public class GlobalExceptionHandler implements ErrorWebExceptionHandler {

  @Override
  public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
    ServerHttpResponse httpResponse = exchange.getResponse();
    setResponseStatus(httpResponse, ex);
    return httpResponse.writeWith(Mono.fromSupplier(() -> {
      DataBufferFactory bufferFactory = httpResponse.bufferFactory();
      try {
        //Not displaying any error msg to client for internal server error
        String errMsgToSend = (httpResponse.getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR) ? "" : ex.getMessage();
        return bufferFactory.wrap(new ObjectMapper().writeValueAsBytes(errMsgToSend));
      } catch (JsonProcessingException e) {
        return bufferFactory.wrap(new byte[0]);
      }
    }));
  }

  private void setResponseStatus(ServerHttpResponse httpResponse, Throwable ex) {
    if (ex instanceof Ex1 || ex instanceof Ex2 || ex instanceof Ex3) {
      httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
    } else {
      httpResponse.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
@RequestMapping(
        path="/getExceptionMono",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<ResponseEntity> getException(){
        return Mono.just(ResponseEntity.badRequest().build());
    }
}
webClient
 .get()
 .uri("/some/url")
 .exchange()
 .flatMap(clientResponse -> {
     if (clientResponse.statusCode().is5xxServerError()) {
        //do something and return some mono
     }
     else if(clientResponse.statusCode().is4xxClientError()) {
        //do something and return some mono
     }
     else {
       //do something and return some mono  
     }
});
 类似资料:
  • 想象一下,我有一个CourseID对象列表(CourseID,Name)。让我们把这个列表称为'CourseNameList'。 当某人将请求发送到“ 然而,在发送结果之前,我还需要追加每个课程的价格。价格将从另一个微服务中检索,并返回Mono对象。 因此,用户将看到带有(ID、名称、价格)的课程列表。价格来源于其他服务。 控制器方法可能如下所示 我尝试了多种方法来返回Flux。但是,我不知道怎么

  • 我想知道在DDD项目中实现反应性Mongo存储库时遇到的一个问题,我使用Java和Spring Boot实现。假设我们有这样的包结构: 我需要我的订单存储库。java我想要一个保存订单的方法: 并在我的应用服务中使用它: 接下来,我想编写MongoOrderRepository,它实现了OrderRepository。假设我将使用ReactiveMongoTemplate。问题是它的所有方法都返回

  • 我有一个例子,我想使用通量。生成,因为我不想进行昂贵的阻塞呼叫,除非/直到用户提出要求。具体来说,我多次调用Elasticsearch(有效地进行分页),直到没有更多点击。我在迭代器中使用标准的阻塞调用实现了这一点 下面是前面使用阻塞的代码: 上面的工作原理很好,因为它等待对ES进行下一次调用,直到(该)订阅者准备好接收下一个数据块。 在下面,我尝试使用Spring的,但问题是在订阅者处理第一个之

  • 我正在尝试使用SpringBoot2.0和新的reactive webFlux库。我想知道如何将通过无阻塞WebClient进行的两个调用的结果返回给我的Springboot API的调用者。我的代码是: 然而,如果我这样称呼它,我得到的回应是 而不是SearchResponse对象的内容。我觉得我可能错过了一个基本的点,这是如何工作的!我的想法是,因为WebClient没有阻塞,所以我可以向we

  • 问题内容: 结果始终为1: 我在phpMyAdmin中运行了$ sql查询,它返回3,所以查询不是问题。$ vote_total全局初始化为0,因此1来自某个地方。我还需要提供什么其他信息来帮助我? 谢谢,瑞安 问题答案: 返回选定的行数,而不是特定行的字段。使用来获取您与您的查询选择的行: 您还可以用来获取一行并获取特定字段: 这将获取第一行(从零开始)并返回第一字段(从零开始)。

  • 问题内容: 我已经写了这段简单的代码: 在我的情况当属。谁能建议/建议出什么问题了? 问题答案: 错误检查和处理是程序员的朋友。检查初始化和执行cURL函数的返回值。并在失败的情况下包含更多信息: *在 手动状态: 成功返回cURL句柄,错误返回 FALSE 。 我观察到该函数在您使用其参数且无法解析域时会返回。如果未使用该参数,则该函数 可能 永远不会返回。但是,请务必始终进行检查,因为该手册并