SpringBoot不处理javax.validation.ConstraintViolationException [英] SpringBoot doesn't handle javax.validation.ConstraintViolationException
问题描述
我已经在我的Entity类中定义了验证电子邮件的模式。在我的验证异常处理程序类中,我为ConstraintViolationException添加了处理程序。我的应用程序使用SpringBoot 1.4.5。
I have defined a pattern for validating email in my Entity class. In my validation exception handler class, I have added handler for ConstraintViolationException. My application utilize SpringBoot 1.4.5.
Profile.java
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "profile")
public class Profile extends AuditableEntity {
private static final long serialVersionUID = 8744243251433626827L;
@Column(name = "email", nullable = true, length = 250)
@NotNull
@Pattern(regexp = "^([^ @])+@([^ \\.@]+\\.)+([^ \\.@])+$")
@Size(max = 250)
private String email;
....
}
ValidationExceptionHandler.java
@ControllerAdvice
public class ValidationExceptionHandler extends ResponseEntityExceptionHandler {
private MessageSource messageSource;
@Autowired
public ValidationExceptionHandler(MessageSource messageSource) {
this.messageSource = messageSource;
}
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex,
WebRequest request) {
List<String> errors = new ArrayList<String>();
....
}
}
当我跑步时我的代码并传递无效的电子邮件地址,我得到以下异常。 handleConstraintViolation中的代码永远不会执行。异常中返回的http状态为500,但我想返回400.我知道如何实现这一点吗?
When I run my code and pass invalid email address, I get the following exception. The code in handleConstraintViolation is never executed. The http status returned in the exception is 500, but I want to return 400. Any idea how I can achieve that?
2017-07-12 22:15:07.078 ERROR 55627 --- [nio-9000-exec-2] o.h.c.s.u.c.UserProfileController : Validation failed for classes [org.xxxx.common.service.user.domain.Profile] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='must match "^([^ @])+@([^ \.@]+\.)+([^ \.@])+$"', propertyPath=email, rootBeanClass=class org.xxxx.common.service.user.domain.Profile, messageTemplate='{javax.validation.constraints.Pattern.message}'}]
javax.validation.ConstraintViolationException: Validation failed for classes [org.xxxx.common.service.user.domain.Profile] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='must match "^([^ @])+@([^ \.@]+\.)+([^ \.@])+$"', propertyPath=email, rootBeanClass=class org.xxxx.common.service.user.domain.Profile, messageTemplate='{javax.validation.constraints.Pattern.message}'}]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:78)
推荐答案
你无法捕获 ConstraintViolationException.class
,因为它没有传播到你的代码层,它被较低层捕获,包裹和在另一种类型下重新抛出。因此,访问您的Web图层的异常不是 ConstraintViolationException
。
You cannot catch ConstraintViolationException.class
because it's not propagated to that layer of your code, it's caught by the lower layers, wrapped and rethrown under another type. So that the exception that hits your web layer is not a ConstraintViolationException
.
在我的情况下,它是 TransactionSystemException
。
我在Spring使用 @Transactional
注释 JpaTransactionManager
。当事务中的某些事情出错时,EntityManager会抛出一个回滚异常,该事务由 JpaTransactionManager
转换为 TransactionSystemException
。
In my case, it's a TransactionSystemException
.
I'm using @Transactional
annotations from Spring with the JpaTransactionManager
. The EntityManager throws a rollback exception when somethings goes wrong in the transaction, which is converted to a TransactionSystemException
by the JpaTransactionManager
.
所以你可以这样做:
@ExceptionHandler({ TransactionSystemException.class })
public ResponseEntity<RestResponseErrorMessage> handleConstraintViolation(Exception ex, WebRequest request) {
Throwable cause = ((TransactionSystemException) ex).getRootCause();
if (cause instanceof ConstraintViolationException) {
Set<ConstraintViolation<?>> constraintViolations = ((ConstraintViolationException) cause).getConstraintViolations();
// do something here
}
}
这篇关于SpringBoot不处理javax.validation.ConstraintViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!