Spring+Hibernate 验证:抛出 Hibernate Exceptions 而不是 Spring 异常

gam*_*may 5 java validation spring hibernate

我有一个简单的项目(详细信息如下),它有一个 Spring bean 并使用 HV 是验证提供程序,用于方法参数验证。

问题:当验证失败时,它会抛出 Hibernate 异常 ( org.hibernate.validator.method.MethodConstraintViolationException)。但我希望它抛出 Spring 异常(org.springframework.web.bind.MethodArgumentNotValidException ),因为 Spring 是包装接口。据我所知,我不在乎谁是验证实现者,只需要处理 Spring 定义的类。

问题一:上面的说法是否正确,是否应该抛出Spring异常?

问题 2:如果 Hibernate 异常是常态,我如何将其映射到友好消息(在 Google 上找不到此信息)

产品经理.java:

@Component
@Validated
public class ProductManager {

    public void createProduct(@Valid Product product) {

    }
}
Run Code Online (Sandbox Code Playgroud)

产品.java:

public class Product {

    private int id;

    @NotNull
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
Run Code Online (Sandbox Code Playgroud)

测试员.java:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/META-INF/applicationContext.xml"})
public class Tester {

    @Autowired
    ProductManager productManager;

    @Test
    public void testCreateProduct() {
        Product p = new Product();

        try {
            productManager.createProduct(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

应用上下文.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <context:annotation-config />
    <context:component-scan base-package="com.gammay.example" />

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <qualifier value="validator"/>
    </bean>

    <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>

</beans>
Run Code Online (Sandbox Code Playgroud)

Tester.java 中打印的异常:

org.hibernate.validator.method.MethodConstraintViolationException:发生以下约束违规:[MethodConstraintViolationImpl [method=public void com.gammay.example.core.ProductManager.createProduct(com.gammay.example.model.Product), parameterIndex=0, parameterName=arg0,kind=PARAMETER,message=可能不为空,messageTemplate={javax.validation.constraints.NotNull.message},rootBean=com.gammay.example.core.ProductManager@12e79d0,rootBeanClass=class com.gammay。 example.core.ProductManager,leafBean=com.gammay.example.model.Product@92acdc,invalidValue=null,propertyPath=ProductManager#createProduct(arg0).name,constraintDescriptor=ConstraintDescriptorImpl{annotation=javax.validation.constraints.NotNull,payloads =[], hasComposingConstraints=true, isReportAsSingleInvalidConstraint=false, elementType=FIELD,definedOn=DEFINED_LOCALLY,groups=[interface javax.validation.groups.Default],attributes={message={javax.validation.constraints.NotNull.message},payload=[Ljava.lang.Class;@7ce531,groups=[Ljava] .lang.Class;@1ab0086}}]] 在 org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:91) ...

ndr*_*one 2

如果你看看 spring 的内部工作原理,MethodValidationInterceptor就会发现 buildValidatorFactory 中有一个private static class HibernateValidatorDelegate。Spring 正在调用配置 Hibernate,HibernateValidator它正在执行实际的验证,因此您会看到它org.hibernate.validator.method.MethodConstraintViolationException