Spring Boot-ControllerAdvice exceptionhandler未使用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

使用最新版本的SpringBoot(1.1.3.RELEASE),我正在尝试一个非常简单的rest应用程序。我有一个异常处理程序来处理由错误输入引起的验证错误。如果我发出POST请求,异常处理程序将激发。但是,如果我有补丁或put请求,它不会启动。可能发生了什么

异常处理程序类

@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"
}