Dubbo参数验证(五)

1、参考

参数验证:http://dubbo.apache.org/en-us/docs/user/demos/parameter-validation.html

2、参数验证

Dubbo中的参数验证基于JSR-303,它是JAVA EE 6中的一项子规范,通过注解的方式用来对 Java Bean中字段的值进行简单验证。Consumer端要调用Provider端的接口,调用接口的话就会有参数用于传递数据,这里的验证指的就是对这个参数进行验证。

2.1、Maven依赖


    javax.validation
    validation-api
    1.0.0.GA


    org.hibernate
    hibernate-validator
    4.2.0.Final

如果使用的jdk比较新的话,需要另外添加如下几个依赖:

		
			javax.xml.bind
			jaxb-api
			2.2.11
		
		
			com.sun.xml.bind
			jaxb-core
			2.2.11
		
		
			com.sun.xml.bind
			jaxb-impl
			2.2.11
		
		
			javax.activation
			activation
			1.1.1
		

 这几个hibernate所依赖的包原来包含在旧版本的jdk中,在新版本中被移除了,好像是从jkd 9开始的,因此需要手动添加。

2.2、示例

创建一个用来传递数据的Bean,在成员之前添加用于验证参数的注解:

import java.io.Serializable;
import java.util.Date;
 
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
 
public class ValidationParameter implements Serializable {
    private static final long serialVersionUID = 7158911668568000392L;
 
    @NotNull // Required 
    @Size(min = 1, max = 20) // range
    private String name;
 
    @NotNull(groups = ValidationService.Save.class) // It is not allowed to be blank when saving. When it is updated, it is allowed to be blank, indicating that the field is not updated 
    @Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
    private String email;
 
    @Min(18) // min value
    @Max(100) // max value
    private int age;
 
    @Past // Must be a past time
    private Date loginDate;
 
    @Future // Must be a future time
    private Date expiryDate;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public Date getLoginDate() {
        return loginDate;
    }
 
    public void setLoginDate(Date loginDate) {
        this.loginDate = loginDate;
    }
 
    public Date getExpiryDate() {
        return expiryDate;
    }
 
    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }
}

 

看一下private String email这个成员:

@NotNull(groups = ValidationService.Save.class) // It is not allowed to be blank when saving. When it is updated, it is allowed to be blank, indicating that the field is not updated
@Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
private String email;

有两条参数验证的注解,第一条是非NULL,后边的注释写black应该是错误的。后边的groups用于区分场景,表示只有调用ValidationService.Save这个方法时才不允许为空,其它场景下允许。

第二条对成员的值进行正则匹配,当然如果email的值是NULL,则不进行匹配,这种情况是通过验证。

服务接口:

public interface ValidationService { // By default, service interfaces are used to differentiate authentication scenarios. For example:@NotNull(groups = ValidationService.class)   
    @interface Save{} // The same name as the method interface, the first letter capitalized, used to distinguish between authentication scene. For example:@NotNull(groups = ValidationService.Save.class),option
    void save(ValidationParameter parameter);
    void update(ValidationParameter parameter);
}

接下来在Provider端正常实现上边的接口,Consumer端调用save或者update方法时,会触发参数验证。

关联验证示例:

import javax.validation.GroupSequence;
 
public interface ValidationService {   
    @GroupSequence(Update.class) // 同时验证Update组规则
    @interface Save{}
    void save(ValidationParameter parameter);
 
    @interface Update{} 
    void update(ValidationParameter parameter);
}

没明白什么是关联验证。

参数验证示例:

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
 
public interface ValidationService {
    void save(@NotNull ValidationParameter parameter); // 验证参数不为空
    void delete(@Min(1) int id); // 直接对基本类型参数验证
}

2.3、配置

验证可发生在Consumer端或者Provider端。

Consumer端:

Provider端:

2.4、异常

捕获异常:

   try {
            parameter = new ValidationParameter();
            validationService.save(parameter);
            System.out.println("Validation ERROR");
        } catch (RpcException e) { // 抛出的是RpcException
            ConstraintViolationException ve = (ConstraintViolationException) e.getCause(); // 里面嵌了一个ConstraintViolationException
            Set> violations = ve.getConstraintViolations(); // 可以拿到一个验证错误详细信息的集合
            System.out.println(violations);
        }

2.5、扩展

参考:http://dubbo.apache.org/en-us/docs/dev/impls/validation.html

 

你可能感兴趣的:(Dubbo)