Spring Boot-ControllerAdvice exceptionhandler未使用put和修补程序请求触发
使用最新版本的SpringBoot(1.1.3.RELEASE),我正在尝试一个非常简单的rest应用程序。我有一个异常处理程序来处理由错误输入引起的验证错误。如果我发出POST请求,异常处理程序将激发。但是,如果我有补丁或put请求,它不会启动。可能发生了什么 异常处理程序类Spring Boot-ControllerAdvice exceptionhandler未使用put和修补程序请求触发,spring,validation,rest,spring-boot,Spring,Validation,Rest,Spring Boot,使用最新版本的SpringBoot(1.1.3.RELEASE),我正在尝试一个非常简单的rest应用程序。我有一个异常处理程序来处理由错误输入引起的验证错误。如果我发出POST请求,异常处理程序将激发。但是,如果我有补丁或put请求,它不会启动。可能发生了什么 异常处理程序类 @ControllerAdvice public class DataValidationExceptionHandler { @ExceptionHandler(value = {ConstraintViola
@ControllerAdvice
public class DataValidationExceptionHandler {
@ExceptionHandler(value = {ConstraintViolationException.class})
public ResponseEntity handleBadInput(ConstraintViolationException ex) {
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}
}
主应用程序类
@Configuration
@ComponentScan
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableTransactionManagement
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
域类
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Size(min=2, max=100)
@NotBlank
private String name;
@URL
private String website;
//Not including getters and setters...
}
存储库类
@RepositoryRestResource(collectionResourceRel = "companies", path = "companies")
public interface CompanyRepository extends PagingAndSortingRepository<Company, Long> {
}
更新2-为了排除故障,我还添加了一个catch-all异常处理程序。对于PUT请求,这个catch all可以处理异常,而不是我所期望的异常(javax.validation.ConstraintViolationException的处理程序)。在调试器中查看异常是什么时,调试器显示-
org.springframework.transaction.TransactionSystemException:无法提交JPA事务;嵌套异常为javax.persistence.RollbackException:提交事务时出错
@ControllerAdvice
public class SystemExceptionHandler {
@ExceptionHandler(value = {Exception.class})
public ResponseEntity handleBadInput(Exception ex) {
return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
因此,Spring似乎正在将javax.validation.ConstraintViolationException的异常包装到另一个异常中。为了查看是否正确处理了包装异常,我还添加了这个处理程序
@ControllerAdvice
public class TransactionExceptionHandler {
@ExceptionHandler(value = {TransactionSystemException.class})
public ResponseEntity handleTxException(TransactionSystemException ex) {
Throwable t = ex.getCause();
if(t instanceof ConstraintViolationException){
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}else {
return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
但问题是,即使TransactionSystemException.class的处理程序也无法处理该异常。只有Exception.class处理程序能够处理它。神秘的
更新3-我现在束手无策。只是没有正确调用异常处理程序。我的下一个测试是查看数据库约束冲突是否得到正确处理。在非常简单的公司模型中,数据库的设置对公司名称具有唯一的约束。因此,如果发生冲突,引发的异常是org.springframework.dao.DataIntegrityViolationException。不会触发catch all Exception.class处理程序或为org.springframework.dao.DataIntegrityViolationException编写的特定处理程序。Boot的json输出如下所示。什么
{
"cause" : {
"cause" : {
"cause" : {
"cause" : null,
"message" : "Duplicate entry 'comp1' for key 'chk_comp_name_unique'"
},
"message" : "Duplicate entry 'comp1' for key 'chk_comp_name_unique'"
},
"message" : "could not execute statement"
},
"message" : "could not execute statement; SQL [n/a]; constraint [chk_comp_name_unique]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}
看起来这将在下一版本的SpringDataREST中修复。
我在github repo中看到了代码更改,因此SDR 2.3 RC1(Fowler)可以使用该修复程序。您确定PUT调用生成了相同的异常吗?您是否在日志或调试器中看到了它?当然……在这两种情况下,javax.validation.ConstraintViolationException。我将发布PUT的堆栈跟踪。在POST的情况下,没有堆栈跟踪,因为触发了exceptionhandler,并且我没有转储任何堆栈跟踪。确定,等待stacktrace:)如果您更改异常处理程序以处理任何异常,是否会产生任何影响?我也尝试过。是的,它似乎正在改变。我有一个单独的@ControllerAdvice类来处理任何异常。对于put请求,将触发exception.class的异常处理程序。对于post请求,将触发javax.validation.ConstraintViolationException的异常处理程序。
{
"cause" : {
"cause" : {
"cause" : {
"cause" : null,
"message" : "Duplicate entry 'comp1' for key 'chk_comp_name_unique'"
},
"message" : "Duplicate entry 'comp1' for key 'chk_comp_name_unique'"
},
"message" : "could not execute statement"
},
"message" : "could not execute statement; SQL [n/a]; constraint [chk_comp_name_unique]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}