Parameter Validation
Parameter verification in dubbo3
Feature description
The parameter verification function is implemented based on JSR303, users only need to identify the verification annotation of the JSR303 standard, and realize the verification by declaring the filter.
Maven dependencies
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
scenes to be used
When the server provides interface services to the outside, it solves various interface parameter verification problems.
Reference use case
https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-validation
How to use
Parameter annotation example
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 // not allowed to be null
@Size(min = 1, max = 20) // length or size range
private String name;
@NotNull(groups = ValidationService.Save.class) // It is not allowed to be empty when saving, and it is allowed to be empty when updating, indicating that the field will not be 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) // minimum value
@Max(100) // maximum 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;
}
}
Group verification example
public interface ValidationService { // By default, validation scenarios can be distinguished by service interface, such as: @NotNull(groups = ValidationService.class)
@interface Save{} // The interface with the same name as the method, the first letter is capitalized, used to distinguish validation scenarios, such as: @NotNull(groups = ValidationService.Save.class), optional
void save(ValidationParameter parameter);
void update(ValidationParameter parameter);
}
Association Validation Example
import javax.validation.GroupSequence;
public interface ValidationService {
@GroupSequence(Update.class) // Verify Update group rules at the same time
@interface Save{}
void save(ValidationParameter parameter);
@interface Update{}
void update(ValidationParameter parameter);
}
Parameter validation example
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public interface ValidationService {
void save(@NotNull ValidationParameter parameter); // validation parameter is not empty
void delete(@Min(1) int id); // directly verify the basic type parameters
}
Validate parameters on the client side
<dubbo:reference id="validationService" interface="org.apache.dubbo.examples.validation.api.ValidationService" validation="true" />
Validate parameters on the server side
<dubbo:service interface="org.apache.dubbo.examples.validation.api.ValidationService" ref="validationService" validation="true" />
Dubbo supports hibernate-validator version <=6.x by default, if you use hibernate-validator 7.x version, please declare the validation parameter as jvalidatorNew
Verify exception information
import javax.validation.ConstraintViolationException;
import javax.validation.ConstraintViolationException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.dubbo.examples.validation.api.ValidationParameter;
import org.apache.dubbo.examples.validation.api.ValidationService;
import org.apache.dubbo.rpc.RpcException;
public class ValidationConsumer {
public static void main(String[] args) throws Exception {
String config = ValidationConsumer.class.getPackage().getName().replace('.', '/') + "/validation-consumer.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
context. start();
ValidationService validationService = (ValidationService)context.getBean("validationService");
// Error
try {
parameter = new ValidationParameter();
validationService. save(parameter);
System.out.println("Validation ERROR");
} catch (RpcException e) { // What is thrown is RpcException
ConstraintViolationException ve = (ConstraintViolationException) e.getCause(); // A ConstraintViolationException is embedded in it
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations(); // You can get a collection of verification error details
System.out.println(violations);
}
}
}
The validation method can be extended, see Validation Extension in the developer manual for the extension method
Last modified January 2, 2023: Enhance en docs (#1798) (95a9f4f6c1)