java - 使用约束注释时如何使用spring boot返回http错误响应
问题描述
我正在使用 React 和 Spring-boot 开发一个项目。到目前为止,我已经成功创建了一个注册页面,将用户(用户名、密码、电子邮件)插入到从 spring boot 管理的 postgres 数据库中。但是,现在我想在后端过滤这个输入,这样我就不会收到不需要的用户名、密码、电子邮件。
经过一些谷歌搜索后,我发现我可以使用@Pattern 和@Size 等注释约束来做到这一点。使用注释目前似乎满足了我的需求。如果有更好的方法,请随时提出更好的方法。
我的问题是如何将唯一的 http 错误消息返回到反应前端。在我看来,每个注释都应该有自己的错误 ID。例如,
@Column(name = "password")
@Pattern(regexp = "[^\s]*", message = "Password should not contain whitespaces")
@Size(min = 8, max = 16, message = "Password should be between 8 and 16 characters")
private String userPassword;
为了在前端通知客户端,我需要以某种方式获取错误 ID 或消息。
使用邮递员发送一些无效输入我收到 400 条错误消息,但返回的 JSON 太复杂了。我不需要太多信息,只需要源错误。
奇怪的是,使用唯一的真实约束
@Column(name = "email", unique = true)
private String userEmail;
给我一个 500 状态错误,而且描述错误的 json 与 400 完全不同。
我只是想用描述错误的简单 json 结构返回 40x 错误。理想情况下,我想处理由注释引起的异常,或者因为我在函数内手动抛出异常。
解决方案
您需要其中之一:
@RestControllerAdvice
@Slf4j
public class ExceptionHandler {
// this catches everything that you don't handle specifically.
@ExceptionHandler({Exception.class})
@ResponseStatus(INTERNAL_SERVER_ERROR)
public ErrorMessage handleException(Exception e) {
log.warn("An unexpected error occurred", e);
return ErrorMessage
.builder()
.cause("Internal server error")
.detail(e.getMessage())
.build();
}
@ResponseStatus(BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
public ErrorMessage handleConstraintViolationException(ConstraintViolationException e) {
log.info(e.getMessage());
List<FieldError> fieldErrors = e.getConstraintViolations()
.stream()
.map(violation -> FieldError
.builder()
.description(violation.getMessage())
.field(violation.getPropertyPath().toString())
.rejectedValue(violation.getInvalidValue())
.build())
.collect(Collectors.toList());
return ErrorMessage
.builder()
.cause("Constraint violation")
.detail("The request was invalid.")
.fieldErrors(fieldErrors)
.build();
}
}
您可以根据需要添加其他处理程序(NOT_FOUND、CONFLICT 等),也可以为其他类型的异常添加更多 BAD_REQUEST 处理程序(MethodArgumentNotValidException、MissingServletRequestParameterException、HttpMessageNotReadableException)。
仔细考虑您返回的错误的结构,因为它们构成您与客户的 API 合同的一部分,并且一旦发布到野外,在更改它们时需要非常小心。此外,在您的响应中使用异常消息时要小心,因为这可能会揭示您的实现细节 - 知道您使用过 Java 和 Spring Boot 可能会让攻击者踏上大门)。
至于唯一的错误代码,那是另一个有趣的世界。我建议让它们保持简单和通用。使用助记符而不是不直观的代码。例如 MandatoryField 比 ABC-00234 更容易理解。
推荐阅读
- node.js - Express 应用程序未在生产中连接到 MongoDB - 不知道为什么?
- android - withContext - ArrayIndexOutOfBoundsException
- laravel - 为什么登录后没有重定向到家?
- r - 如何计算产品从购买第一天起的移动平均年龄?
- r - R循环遍历lm函数中的自变量
- python - 尝试向 RESTful API 发送请求时收到“404”
- java - 如何向 Resttemplate exchange() 函数添加多个 uriVariable
- arrays - 如何将列表框中的所有选定数据存储在VBA中的数组中
- ruby-on-rails - SimpleForm(你能设置默认的 label_method 和 value_method 参数吗?)
- python - Keras fit_generator 一次训练一个样本,而我从生成器中生成多个样本