我是靠谱客的博主 真实爆米花,最近开发中收集的这篇文章主要介绍Spring Bean Validation,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我们都知道在Spring MVC中要使用Bean Validation验证Controller类中的方法入参可以很轻松的做到,具体可以查相关资料。但是相对于数据层就没有找到优雅的验证方式。不久前看Spring中的扩展Spring的BeanPostProcessor,看到了Spring支持依赖注入验证和方法级别验证的支持。下面我就把自己写的例子给大家分享一下。

1、Bean

需要验证的Bean对象。

package com.spring.framework.carl.user.entity;

import lombok.Data;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

@Data
public class User {

    @NotNull(message = "用户ID不能为空")
    private Integer id;

    @NotNull(message = "用户名不能为空")
    private String username;

    private String password;

    private BigDecimal amount;

}

2、Spring xml 配置

添加Spring对Bean验证后处理器与方法验证的后处理器。

<?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.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.spring.framework.carl.validate" />

    <!--注册Bean验证后处理器-->
    <bean class="org.springframework.validation.beanvalidation.BeanValidationPostProcessor" />

    <!--注册方法验证的后处理器-->
    <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
</beans>

3、Interface – 用来验证的方法

package com.spring.framework.carl.validate;

import com.spring.framework.carl.user.entity.User;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

/**
 * @author carl.zhao
 * @version 1.0.0
 * @see UserService
 * @since 1.0.0 2016-10-10
 */
@Validated
public interface UserService {

    @NotNull User findUserByCondition(@NotNull @Valid User condition);

}

4、Implement

package com.spring.framework.carl.validate;

import com.spring.framework.carl.user.entity.User;
import org.springframework.stereotype.Service;

/**
 * @author carl.zhao
 * @version 1.0.0
 * @see UserServiceImpl
 * @since 1.0.0 2016-10-10
 */
@Service
public class UserServiceImpl implements UserService {
    @Override
    public User findUserByCondition(User condition) {
        return condition;
    }
}

5、TestCase

package com.spring.framework.carl.validate;

import com.spring.framework.carl.user.entity.User;
import lombok.extern.log4j.Log4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;

/**
 * @author carl.zhao
 * @version 1.0.0
 * @see UserServiceTest
 * @since 1.0.0 2016-10-10
 */
@RunWith(SpringJUnit4ClassRunner.class)
@Log4j
@ContextConfiguration(locations = "classpath:validate-bean.xml")
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testFindUserByCondition(){
        try {
            User user = new User();
            user.setId(4);             // 注释点1 
            user.setUsername("carl");  // 注释点2
            final User userFind = userService.findUserByCondition(user);
            System.out.println(userFind);
        } catch (ValidationException e){
            if(e instanceof ConstraintViolationException){
                StringBuffer sb = new StringBuffer();
                final Set<ConstraintViolation<?>> constraintViolations = 
                ((ConstraintViolationException) e).getConstraintViolations();
                for(ConstraintViolation constraint : constraintViolations){
                    sb.append(constraint.getMessage());
                }
                log.error(sb.toString(), e);
            } else {
                log.error(e.getMessage(), e);
            }
        } catch (Exception e){
            log.error(e.getMessage(), e);
        }
    }

}

6、Result

1)注释掉第5点的注释点1:
这里写图片描述

2)注释掉第5点的注释点2:
这里写图片描述

注意:而且在接口上的@Valid标签也是控制是否对这个对象的具体参与进行检测。这只是一个小例子,希望能给大家起到抛砖引玉的效果。

7、自定义异常

上面的方法验证参数异常是由spring控制的,那么我们可不可以进行自定义异常处理呢?答案是肯定的。
1) MyMethodValidationPostProcessor

public class MyMethodValidationPostProcessor extends MethodValidationPostProcessor {

    protected Advice createMethodValidationAdvice(Validator validator) {
        return (validator != null ? new MyMethodValidationInterceptor() : new MyMethodValidationInterceptor());
    }
}

2) MyMethodValidationInterceptor

public class MyMethodValidationInterceptor extends MethodValidationInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object returnValue;
        try {
            returnValue = super.invoke(invocation);
        } catch (Exception e){
            throw new RuntimeException("自定义异常信息......");
        }
        return returnValue;
    }
}

3) 配置文件修改

    <!--注册Bean验证后处理器-->
    <bean class="org.springframework.validation.beanvalidation.BeanValidationPostProcessor">
        <!--<property name="validator" ref="validator" />-->
    </bean>

    <!--注册方法验证的后处理器-->
    <!-- spring 方法验证器
    <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
    -->
    <!-- 自定义方法验证器 -->
    <bean class="com.spring.framework.carl.validate.MyMethodValidationPostProcessor"/>

运行结果:

这里写图片描述

传递正常的参数,可以返回正确的结果:

这里写图片描述

参考文章:Spring3.1 对Bean Validation规范的新支持(方法级别验证)

最后

以上就是真实爆米花为你收集整理的Spring Bean Validation的全部内容,希望文章能够帮你解决Spring Bean Validation所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部