首页 > 解决方案 > ServerRequest bodyToFlux 正在返回 415

问题描述

我在 spring webflux 中编写了一个休息异常处理程序:-

@Slf4j
@Component
@Order(-2)//So that our exception handler gets picked before DefaultErrorWebExceptionHandler
public class RestWebExceptionHandler extends
    AbstractErrorWebExceptionHandler {

  public RestWebExceptionHandler(
      ErrorAttributes errorAttributes,
      WebProperties.Resources resourceProperties,
      ApplicationContext applicationContext,
      ServerCodecConfigurer serverCodecConfigurer) {
    super(errorAttributes, resourceProperties, applicationContext);
    this.setMessageWriters(serverCodecConfigurer.getWriters());
  }

  @Override
  protected RouterFunction<ServerResponse> getRoutingFunction(
      ErrorAttributes errorAttributes) {
    return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
  }

  /**
   * Renders the error response.
   *
   * @param serverRequest
   * @return
   */
  private Mono<ServerResponse> renderErrorResponse(ServerRequest serverRequest) {
    Map<String, Object> body = getErrorAttributes(serverRequest, ErrorAttributeOptions.of(
        Include.EXCEPTION, Include.MESSAGE, Include.STACK_TRACE));
    String exceptionClass = (String) body.get("exception");
    return serverRequest.bodyToFlux(Metric.class).collectList().flatMap(metrics -> {
      log.warn("error {}", metrics);
      return respondWith(body, exceptionClass);
    });
  }

  /**
   * Responds with error response based on the exception class present in errorAttributes.
   *
   * @param body
   * @param exceptionClass
   * @return
   */
  private Mono<ServerResponse> respondWith(Map<String, Object> body, String exceptionClass) {
    if (exceptionClass.equals(IllegalArgumentException.class.getName()) || exceptionClass
        .equals(ServerWebInputException.class.getName()) || exceptionClass.equals(
        TypeMismatchException.class.getName())) {
      return respondWithBadRequest(body);
    }
    return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).body(BodyInserters.fromValue(
        body));
  }

  /**
   * Responds with bad request server response.
   *
   * @param body
   * @return
   */
  private Mono<ServerResponse> respondWithBadRequest(Map<String, Object> body) {
    body.remove("error");
    body.put("status", HttpStatus.BAD_REQUEST.value());
    return ServerResponse.status(HttpStatus.BAD_REQUEST).body(BodyInserters.fromValue(body));
  }

我得到的是 415 的空响应,而不是 500 我正在构建的自定义响应。我觉得当我从 serverRequest 获取请求正文时出现错误,因为警告日志log.warn("error {}", metrics);没有打印在日志中。

Metricobject 是我的控制器正在使用的请求正文。

从 serverRequest 对象中提取请求正文是否有问题?

标签: spring-bootreactive-programmingspring-webflux

解决方案


推荐阅读