提问人:brain-dot-isEmpty 提问时间:3/2/2023 最后编辑:Eritreanbrain-dot-isEmpty 更新时间:3/2/2023 访问量:1107
是否可以在 spring boot 中用一个@ExceptionHandler处理多个异常?
Is it possible to handle multiple exceptions with one @ExceptionHandler in spring boot?
问:
我有这段代码,我应该在其中返回自定义的错误消息和错误代码。它工作正常,但问题是它非常冗余。我想知道是否可以用一个@ExceptionHandler处理所有这些自定义异常。
@ControllerAdvice
public class HandleExceptions {
@ExceptionHandler(value = CustomException1.class)
public ResponseEntity<Object> handleCustomException1(CustomException1 e) {
HttpStatus status = HttpStatus.NOT_FOUND;
DataResponse data = new DataResponse("custom status code for exception 1", e.getMessage());
ExceptionResponse exceptionResponse = new ExceptionResponse(data);
return new ResponseEntity<>(ExceptionResponse, status);
}
@ExceptionHandler(value = CustomException2.class)
public ResponseEntity<Object> handleCustomException2(CustomException2 e) {
HttpStatus status = HttpStatus.NOT_FOUND;
DataResponse data = new DataResponse("custom status code for exception 2", e.getMessage());
ExceptionResponse exceptionResponse = new ExceptionResponse(data);
return new ResponseEntity<>(ExceptionResponse, status);
}
@ExceptionHandler(value = CustomException3.class)
public ResponseEntity<Object> handleCustomException3(CustomException3 e) {
HttpStatus status = HttpStatus.BAD_REQUEST;
DataResponse data = new DataResponse("custom status code for exception 3", e.getMessage());
ExceptionResponse exceptionResponse = new ExceptionResponse(data);
return new ResponseEntity<>(ExceptionResponse, status);
}
public class ExceptionResponse {
private final DataResponse data;
}
public class DataResponse {
private String statusCode;
private String message;
}
自定义错误类都如下所示:
public class CustomException extends RuntimeException{
public CustomException(String message){
super(message);
}
}
响应的示例如下:
Data: {
status: 1111,
message: user not found
}
答:
您可以创建将泛型作为参数的单个方法,并使用语句检查异常的类型并相应地修改响应。RuntimeException
if/else
下面的方法检查异常的类型,并在 DataResponse 对象中设置相应的 HTTP 状态代码和错误消息。如果异常不是自定义异常之一,则返回一般错误消息和状态代码。
@ControllerAdvice
public class HandleExceptions {
@ExceptionHandler(value = RuntimeException.class)
public ResponseEntity<Object> handleCustomException(RuntimeException e) {
HttpStatus status;
DataResponse data;
if (e instanceof CustomException1) {
status = HttpStatus.NOT_FOUND;
data = new DataResponse("custom status code for exception 1", e.getMessage());
} else if (e instanceof CustomException2) {
status = HttpStatus.NOT_FOUND;
data = new DataResponse("custom status code for exception 2", e.getMessage());
} else if (e instanceof CustomException3) {
status = HttpStatus.BAD_REQUEST;
data = new DataResponse("custom status code for exception 3", e.getMessage());
} else {
// Handle any other exceptions here
status = HttpStatus.INTERNAL_SERVER_ERROR;
data = new DataResponse("unknown error", e.getMessage());
}
ExceptionResponse exceptionResponse = new ExceptionResponse(data);
return new ResponseEntity<>(exceptionResponse, status);
}
}
Surya Teja Chavali 的方法肯定有效,但为了可读性,也可以做得更好 (?)。
保留多个方法,每个方法都接受不同的异常,以免在代码中引入巨大的 if-else 混乱。
然后只需添加一个“普通”私有方法,然后该方法接受为参数并处理所有内容Throwable
@ControllerAdvice
public class HandleExceptions {
@ExceptionHandler(value = CustomException1.class)
public ResponseEntity<Object> handleCustomException1(CustomException1 e) {
DataResponse data = new DataResponse("custom status code for exception 1", e.getMessage());
return handleCustomException2(e, data, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(value = CustomException2.class)
public ResponseEntity<Object> handleCustomException2(CustomException2 e) {
DataResponse data = new DataResponse("custom status code for exception 2", e.getMessage());
return handleException(e, data, HttpStatus.NOT_FOUND);
}
private ResponseEntity<ExceptionResponse> handleException(Throwable t, DataResponse data, HttpStatus status) {
ExceptionResponse exceptionResponse = new ExceptionResponse(data);
return new ResponseEntity<>(ExceptionResponse, status);
}
}
你也无法用这种方法删除所有冗余,但它的可读性会更高一些。
我认为在这种情况下,冗余并不是真正的问题。实际代码实际上并不相同 - 您有不同的状态代码和每个状态代码的不同消息。因此,我认为,通过尝试组合这些方法只是为了节省几行代码,从而降低代码的可读性。
您也可以使用 将 你的 移动到注释并删除包装器。这样一来,你就把样板从你的逻辑中移开了。但这更像是个人喜好。ResponseStatus
ResponseEntity
@ResponseBody
@ExceptionHandler(value = CustomException1.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ExceptionResponse handleCustomException1(CustomException1 e) {
DataResponse data = new DataResponse("custom status code for exception 1", e.getMessage());
return new ExceptionResponse(data);
}
使用代替时,您还可以删除注释。@RestControllerAdvice
@ControllerAdvice
@ResponseBody
具有超级的 Alternativ 解决方案:
public class CustomException extends RuntimeException {
private final HttpStatus httpStatus;
private final String statusCode;
public CustomException(HttpStatus httpStatus, String statusCode, String message) {
super(message);
this.httpStatus = httpStatus;
this.statusCode = statusCode;
}
}
public class CustomException1 extends CustomException {
public CustomException1(String message) {
super(HttpStatus.NOT_FOUND, "custom status code for exception 1", message);
}
}
// ... similar for 2 and 3
@ControllerAdvice
public class HandleExceptions {
@ExceptionHandler(value = CustomException.class)
public ResponseEntity<Object> handleCustomException(CustomException e) {
DataResponse data = new DataResponse(e.getStatusCode, e.getMessage());
ExceptionResponse exceptionResponse = new ExceptionResponse(data);
return new ResponseEntity<>(exceptionResponse, e.httpStatus);
}
}
上一个:使用 CRC 的冗余存储
下一个:根据分数从字典中删除多余的元组
评论