如何处理春季数据完整性暴力异常?
2022-09-01 23:17:36
我需要在我的Spring 3.0应用程序中显示自定义消息。我有一个带有Hibernate的数据库,有几个约束。我对如何以一种好的方式处理有疑问。我想知道是否有一种方法可以将异常与属性文件中的消息集进行映射,就像在约束验证中一样。我可以以任何方式自动处理它,还是必须在每个控制器中捕获此异常?DataIntegrityViolationException
我需要在我的Spring 3.0应用程序中显示自定义消息。我有一个带有Hibernate的数据库,有几个约束。我对如何以一种好的方式处理有疑问。我想知道是否有一种方法可以将异常与属性文件中的消息集进行映射,就像在约束验证中一样。我可以以任何方式自动处理它,还是必须在每个控制器中捕获此异常?DataIntegrityViolationException
在违反约束的情况下显示用户友好消息的问题是,当Hibernate的被翻译成Spring的时,约束名称会丢失。ConstraintViolationException
DataIntegrityViolationException
但是,您可以自定义此转换逻辑。如果用于访问休眠,则可以为其提供自定义(请参阅)。此异常转换器可以将 a 转换为您自己的异常类,同时保留约束名称。LocalSessionFactoryBean
SQLExceptionTranslator
LocalSessionFactoryBean.jdbcExceptionTranslator
ConstraintViolationException
我在 ExceptionInfoHandler
中处理,查找根本原因消息中出现的 DB 约束,并通过以下方式将其转换为 i18n 消息:DataIntegrityViolationException
constraintCodeMap
@ControllerAdvice(annotations = RestController.class)
@Order(Ordered.HIGHEST_PRECEDENCE + 5)
public class ExceptionInfoHandler {
@Autowired
private final MessageSourceAccessor messageSourceAccessor;
private static Map<String, String> CONSTRAINS_I18N_MAP = Map.of(
"users_unique_email_idx", EXCEPTION_DUPLICATE_EMAIL,
"meals_unique_user_datetime_idx", EXCEPTION_DUPLICATE_DATETIME);
@ResponseStatus(value = HttpStatus.CONFLICT) // 409
@ExceptionHandler(DataIntegrityViolationException.class)
@ResponseBody
public ErrorInfo conflict(HttpServletRequest req, DataIntegrityViolationException e) {
String rootMsg = ValidationUtil.getRootCause(e).getMessage();
if (rootMsg != null) {
String lowerCaseMsg = rootMsg.toLowerCase();
for (Map.Entry<String, String> entry : CONSTRAINS_I18N_MAP.entrySet()) {
if (lowerCaseMsg.contains(entry.getKey())) {
return logAndGetErrorInfo(req, e, VALIDATION_ERROR, messageSourceAccessor.getMessage(entry.getValue()));
}
}
}
return logAndGetErrorInfo(req, e, DATA_ERROR);
}
...
}
可以通过添加/编辑具有重复邮件的用户或具有重复日期时间的膳食,在我的Java Enterprise培训应用程序中进行模拟。
更新:
其他解决方案:使用基于控制器的异常处理:
@RestController
@RequestMapping("/ajax/admin/users")
public class AdminAjaxController {
@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<ErrorInfo> duplicateEmailException(HttpServletRequest req, DataIntegrityViolationException e) {
return exceptionInfoHandler.getErrorInfoResponseEntity(req, e, EXCEPTION_DUPLICATE_EMAIL, HttpStatus.CONFLICT);
}