我创建了一个通用异常DTO,它也扩展了RuntimeException。通过这种方式,可以在应用程序和DTO中使用它。问题是当我将DTO应用于ResponseEntity构造函数时。然后我得到了额外的整个堆栈跟踪:
{
"cause": null,
"stackTrace": [
{
"methodName": "handleConstraintViolations",
"fileName": "ProductExceptionHandler.java",
"lineNumber": 66,
"className": "api.product.infrastructure.ProductExceptionHandler",
"nativeMethod": false
},
{
"methodName": "invoke0",
"fileName": "NativeMethodAccessorImpl.java",
"lineNumber": -2,
"className": "sun.reflect.NativeMethodAccessorImpl",
"nativeMethod": true
},
{
"methodName": "invoke",
"fileName": "NativeMethodAccessorImpl.java",
"lineNumber": 62,
"className": "sun.reflect.NativeMethodAccessorImpl",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "DelegatingMethodAccessorImpl.java",
"lineNumber": 43,
"className": "sun.reflect.DelegatingMethodAccessorImpl",
"nativeMethod": false
},
{
"methodName": "invoke",
"fileName": "Method.java",
"lineNumber": 498,
"className": "java.lang.reflect.Method",
"nativeMethod": false
},
{
"methodName": "doInvoke",
"fileName": "InvocableHandlerMethod.java",
"lineNumber": 205,
"className":
"org.springframework.web.method.support.InvocableHandlerMethod",
"nativeMethod": false
},
....
"status": "UNPROCESSABLE_ENTITY",
"message": "Constraint violation(s)",
"errors": [
"name size must be between 1 and 2147483647"
],
"localizedMessage": "Constraint violation(s)",
"suppressed": []
}
我的例外DTO课程:
@Getter
@EqualsAndHashCode(callSuper = true)
public class ProductException extends RuntimeException implements Serializable {
private final HttpStatus status;
private final String message;
private final String[] errors;
public ProductException(HttpStatus status, String message, String... errors) {
this.status = status;
this.message = message;
this.errors = errors;
}
public ProductException(HttpStatus status, String message, Set<ConstraintViolation<?>> constraintViolation) {
this.status = status;
this.message = message;
this.errors = constraintViolation.stream()
.map(violation -> violation.getPropertyPath().toString() + " " + violation.getMessage())
.toArray(String[]::new);
}
}
而我称之为:
@ExceptionHandler(TransactionSystemException.class)
public ResponseEntity<ProductException> handleConstraintViolations(TransactionSystemException tse) {
ConstraintViolationException cve = (ConstraintViolationException) tse.getMostSpecificCause();
ProductException productException = new ProductException(HttpStatus.UNPROCESSABLE_ENTITY, "Constraint violation(s)", cve.getConstraintViolations());
return new ResponseEntity<>(productException, new HttpHeaders(), productException.getStatus());
我有两个解决方案,首先是创建适配器,将我的Exception转移到一个非扩展的RuntimeException,另一个想法是在我的Exception中创建一个类似.toBody()的方法。最好的方法是阻止ResponseEntity添加“cause”,“stacktrace”等属性。任何想法?
首先是创建适配器,它将我的Exception转移到一个非扩展的RuntimeException
在我看来,这是你最好的选择。通过这样做,您可以很好地控制将获得异常的客户端可用的信息(在您的应用程序中或作为DTO,如您所说)。
在你的@ExceptionHandler
中你只需要绑定需要返回的有用信息(也许记录应该记录的内容)。