spring引导返回200,并将“ok”errorattributes附加到正常的主体响应中

46scxncf  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(269)

spring boot starter版本:2.3.4.0
springweb版本5.2.8.0发布
我的get请求开始响应,并在响应体中附加了无关的“ok”errorattributes,这会中断上游客户机上的所有json反序列化

HTTP/1.1 200 
Date: Tue, 26 Jan 2021 07:44:00 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
X-Trace-Id: 55418518fcaa412b
X-Span-Id: 55418518fcaa412b
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: HEAD, GET, OPTIONS, POST, PUT, PATCH, DELETE
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: *
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff

{
    "id": "ab160a6c-fe00-4eff-a63d-7c10e1c0607c",
    "nickName": "Test User",
    "emailAddress": "test.user@test-domain.com",
    "phoneNumber": null,
    "firstName": "Test",
    "lastName": "User'",
    "location": {
        "id": "a77381f2-5c89-4134-bdad-229ad5e7c9e2",
        "latitude": null,
        "longitude": null,
        "country": "DE",
        "stateOrRegion": null,
        "city": null
    },,
    "avatarUrl": null,
    "role": "DEFAULT",
    "invitationLink": "https://www.test-domain.com/app/app-invite/b666ee33-2046-4ea3-af80-f310756a2eac",
    "invitee": null
}{
    "timestamp": "2021-01-26T07:44:00.826+00:00",
    "status": 200,
    "error": "OK",
    "message": "",
    "path": "/api/users/ab160a6c-fe00-4eff-a63d-7c10e1c0607c"
}

我被困在这两天,并想知道是否有人知道这个问题和如何解决它。
更新我有异常处理程序,返回不同的json模型:

@ResponseBody
  @ResponseStatus(HttpStatus.CONFLICT)
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public ErrorModel handleValidationExceptions(@Nonnull final MethodArgumentNotValidException ex) {
    log.error("Error executing request:", ex);

    final List<PropertyErrorModel> propertyErrors = ex.getBindingResult()
            .getFieldErrors()
            .stream()
            .map(this::buildProperty)
            .collect(toList());
    final List<String> globalMessages = ex.getBindingResult().getGlobalErrors()
            .stream()
            .map(ObjectError::getDefaultMessage)
            .filter(Objects::nonNull)
            .collect(toList());
    return getErrorModelBuilder()
            .globalErrors(globalMessages)
            .propertyErrors(propertyErrors)
            .build();
  }

  @ResponseBody
  @ResponseStatus(HttpStatus.CONFLICT)
  @ExceptionHandler(ConstraintViolationException.class)
  public ErrorModel handleConstraintViolation(@Nonnull final ConstraintViolationException ex) {
    log.error("Error executing request:", ex);

    final List<PropertyErrorModel> propertyErrors = ex.getConstraintViolations()
            .stream()
            .map((viol) -> {
              return PropertyErrorModel.builder()
                      .property(viol.getPropertyPath().toString())
                      .rejectedValue(viol.getInvalidValue())
                      .message(viol.getMessage())
                      .build();
            })
            .collect(toList());
    final List<String> globalMessages = List.of(ex.getMessage());
    return getErrorModelBuilder()
            .code("validation.invalid.property")
            .globalErrors(globalMessages)
            .propertyErrors(propertyErrors)
            .build();
  }

  @ResponseBody
  @ResponseStatus(HttpStatus.CONFLICT)
  @ExceptionHandler(ValidationException.class)
  public ErrorModel handleValidationException(@Nonnull final ValidationException ex) {
    log.error("Error executing request:", ex);

    final ErrorModel error = ex.getError();
    if (error != null) {
      return getErrorModelBuilder()
              .code(firstNonNull(error.getCode(), "validation.failed"))
              .globalErrors(error.getGlobalErrors())
              .propertyErrors(error.getPropertyErrors())
              .build();
    }

    final List<PropertyErrorModel> propertyErrors = emptyIfNull(ex.getPropertyErrors());
    final List<String> globalMessages = List.of(ex.getMessage());
    return getErrorModelBuilder()
            .code("validation.failed")
            .globalErrors(globalMessages)
            .propertyErrors(propertyErrors)
            .build();
  }

  @SneakyThrows
  @ResponseBody
  @ResponseStatus(HttpStatus.CONFLICT)
  @ExceptionHandler(AlreadyExistsException.class)
  public ErrorModel handleAlreadyExistsException(@Nonnull final AlreadyExistsException ex) {
    log.error("Error executing request:", ex);

    final Object domain = ex.getDomain();
    if (domain == null) {
      final List<String> globalMessages = List.of(ex.getMessage());
      return getErrorModelBuilder()
              .code("validation.failed")
              .globalErrors(globalMessages)
              .build();
    }

    final String domainJson = objectMapper.writeValueAsString(domain);
    final List<String> globalMessages = List.of(ex.getMessage(), domainJson);
    return getErrorModelBuilder()
            .code("validation.failed")
            .globalErrors(globalMessages)
            .build();
  }

  @ResponseBody
  @ResponseStatus(HttpStatus.CONFLICT)
  @ExceptionHandler(UnsupportedFilterPropertyException.class)
  public ErrorModel handleUnsupportedFilterPropertyException(@Nonnull final UnsupportedFilterPropertyException ex) {
    log.error("Error executing request:", ex);

    if (ex.getPropertyError() != null) {
      return getErrorModelBuilder()
              .code("validation.failed")
              .propertyErrors(ex.getPropertyError())
              .build();
    }

    final List<String> globalMessages = List.of(ex.getMessage());
    return getErrorModelBuilder()
            .code("validation.failed")
            .globalErrors(globalMessages)
            .build();
  }

  @ResponseBody
  @ResponseStatus(HttpStatus.NOT_FOUND)
  @ExceptionHandler(NotFoundException.class)
  public ErrorModel handleNotFoundException(@Nonnull final NotFoundException ex) {
    log.warn("Error executing request:", ex);

    final List<String> globalMessages = List.of(ex.getMessage());
    return getErrorModelBuilder()
            .code("resource.notfound")
            .globalErrors(globalMessages)
            .build();
  }

  @ResponseBody
  @ExceptionHandler(Throwable.class)
  public ResponseEntity<ErrorModel> fallbackErrorHandler(@Nonnull final Throwable ex) {
    log.error("Error executing request:", ex);

    final Class<?> errorClass = ex.getClass();
    return Optional.ofNullable(errorCodedExceptions.get(errorClass))
            .map((errorCode) -> getCodedError(ex, errorCode))
            .orElseGet(() -> getDefaultInternalServerError(ex));
  }
vfhzx4xs

vfhzx4xs1#

过滤器中旧的脏上下文导致的问题。当抛出异常时,筛选器执行未能清理数据上下文,但不幸的是,在跟踪启动之前,此操作过早失败。错误日志从未以适当的trace.id出现在我们的kibana日志中(我们的跟踪筛选器优先级不够高)
然而,需要进一步研究的是,过滤器中的上下文和故障(与spring框架完全无关)如何允许过滤器链执行继续并调用控制器并返回 200 然后用 200 “确定”信息。

相关问题