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