Configure parameters for startup verification
If the configuration file does not contain the relevant configuration, the following exception will occur when ** starts:
Description: Binding to target com.toby.provide.ApplicationProperties@31da6b2e failed: Property: Feichao.info. name Value: null Reason: The name cannot be empty.Copy the code
Fat toward small voice force force: improve code stability, fat toward think the best way is to prevent in advance. In a real project, we configure various parameters in the configuration file. However, as we all know, the configuration parameters of different environments will be different. It is inevitable that some key parameters are missing in the configuration file of an environment due to human negligence. It is bound to be an inefficient and unreliable way to check by naked eyes. If you do not check this way, it is easy to trigger a pit in a particular scenario. But you use this way, do a lot of startup verification, once the parameters are not legal, the project can not start, do prevent!
Controller
HelloDTO
@Data
public class HelloDTO {
@NotBlank
private String name;
@Min(0)
@Max(150)
private int age;
}
Copy the code
HelloController
@RestController
public class HelloController {
@RequestMapping("/controllerValid")
public String controllerValid(@RequestBody @Valid HelloDTO helloDTO) {
return "ok"; }}Copy the code
Request parameters are
{
"name":"The fat." "."age": 151}Copy the code
Is displayed, a verification exception occurs
org.springframework.web.bind.MethodArgumentNotValidException
Copy the code
Service
HelloDTO
@Data
public class HelloDTO {
@NotBlank
private String name;
@Min(0)
@Max(150)
private int age;
}
Copy the code
AService
public interface AService {
int insertUser(HelloDTO helloDTO);
}
Copy the code
AServiceImpl
@Service
public class AServiceImpl implements AService {
@Autowired
private BService bService;
@Override
public int insertUser(HelloDTO helloDTO) {
returnbService.insertUser(helloDTO); }}Copy the code
BService
public interface BService {
int insertUser(@Valid HelloDTO helloDTO);
}
Copy the code
BServiceImpl
@Service
@Slf4j
@Validated
public class BServiceImpl implements BService {
@Override
public int insertUser(HelloDTO helloDTO) {
log.info("BService insertUser...");
return 0; }}Copy the code
Unit testing
@RunWith(SpringRunner.class)
@SpringBootTest
public class AserviceTest {
@Autowired
private BService bService;
@Test
public void testInsertUser(a) throws Exception {
HelloDTO helloDTO = newHelloDTO(); bService.insertUser(helloDTO); }}Copy the code
Output verification exception information:
javax.validation.ConstraintViolationException
Copy the code
Dubbo
Dubbo’s official documentation has been very detailed, the address is: dubbo.apache.org/zh-cn/docs/…
The parameter validation function is implemented based on JSR303. The user only needs to identify the JSR303 standard validation annotation and implement the validation by declaring filter.
Maven rely on
< the dependency > < groupId > javax.mail. 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 >Copy the code
The sample
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 // Null is not allowed
@Size(min = 1, max = 20) // Length or size range
private String name;
@NotNull(groups = ValidationService.Save.class) // The field cannot be empty when saved, but can be empty when updated, 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) / / the minimum
@Max(100) / / Max
private int age;
@Past // Must be a past time
private Date loginDate;
@Future // Must be for a future time
private Date expiryDate;
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail(a) {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge(a) {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getLoginDate(a) {
return loginDate;
}
public void setLoginDate(Date loginDate) {
this.loginDate = loginDate;
}
public Date getExpiryDate(a) {
return expiryDate;
}
public void setExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate; }}Copy the code
Group validation Example
public interface ValidationService { @notnull (groups = validationService.class)
@interface Save{} / / interface and the method of the same name, capitalize the first letter, is used to distinguish between validation scenarios, such as: @ NotNull (groups = ValidationService. Save. Class), optional
void save(ValidationParameter parameter);
void update(ValidationParameter parameter);
}
Copy the code
Example of association verification
import javax.validation.GroupSequence;
public interface ValidationService {
@GroupSequence(Update.class) // Validate the Update group rules as well
@interface Save{}
void save(ValidationParameter parameter);
@interface Update{}
void update(ValidationParameter parameter);
}
Copy the code
Parameter Verification Example
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public interface ValidationService {
void save(@NotNull ValidationParameter parameter); // Verify that the parameter is not null
void delete(@Min(1) int id); // Validate the basic type parameters directly
}
Copy the code
configuration
Validate parameters on the client side
<dubbo:reference id="validationService" interface="org.apache.dubbo.examples.validation.api.ValidationService" validation="true" />
Copy the code
Validate parameters on the server side
<dubbo:service interface="org.apache.dubbo.examples.validation.api.ValidationService" ref="validationService" validation="true" />
Copy the code
Verifying 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) { // RpcException is thrown
ConstraintViolationException ve = (ConstraintViolationException) e.getCause(); / / embedded inside a ConstraintViolationExceptionSet<ConstraintViolation<? >> violations = ve.getConstraintViolations();// Get a collection of validation error detailsSystem.out.println(violations); }}}Copy the code
1. Supported since version 2.1.0, you can refer to the sample code in the Dubbo project (github.com/apache/incu…) for how to use it.
2. The authentication mode can be extended. For the extension mode, see authentication Extension in the Developer manual (dubbo.apache.org/zh-cn/docs/…).
Tool class verification
ValidationUtils
public class ValidationUtils {
private static Validator validator = Validation
.byProvider(HibernateValidator.class)
.configure()
.failFast(true)
.buildValidatorFactory()
.getValidator();
public static <T> void validate(T obj) {
Set<ConstraintViolation<T>> validate = validator.validate(obj);
for (ConstraintViolation<T> violation : validate) {
// Note that in real business
// This will be initialized according to violation
// Then the custom exception is thrown}}}Copy the code
Unit testing
@Test
public void testValidationUtils(a) throws Exception {
HelloDTO helloDTO = new HelloDTO();
ValidationUtils.validate(helloDTO);
}
Copy the code
Type on the blackboard and underline
The above five examples of verification methods are all based on hibernate-validate. But if you’re careful, you’ll notice that when you search for hibernate-validate, there’s only ** Controller ** on the web, so you’ll get code examples from multiple layers that cover almost all of your scenarios.
Also note that the controller layer throws a validation exception of the type
org.springframework.web.bind.MethodArgumentNotValidException
Copy the code
The type of validation exception thrown by the service layer is
javax.validation.ConstraintViolationException
Copy the code
Tool class verification, you need to get the parameter processing, and then custom exception thrown. So be careful when doing global exceptions.
Of course, this verification method does not only make the parameter check ratio
if (helloDTO.getAge() <= 0) {
/ /...
}
Copy the code
A lot of elegant, but also support custom annotations to achieve verification rules, internationalization, group verification, etc., these specific use of your project, you can go to see.
Of course, there are many ways to improve the stability of the code, but Fei Zhao believes that the way of parameter verification, cost and effect is one of the highest cost-effective, do you have any way to improve the stability of the code? Leave a message telling Fat Chao.