Параметры конфигурации проверяются при запуске
Если в конфигурационном файле нет соответствующей конфигурации, то **启动时** Произойдет следующее исключение:
Description:
Binding to target com.toby.provide.ApplicationProperties@31da6b2e failed:
Property: feichao.info.name
Value: null
Reason: 名字不能为空,请注意检查,参考值为:肥朝。
Фэй Чао прошептал: Фей Чао считает, что лучший способ повысить надежность кода — предотвратить его заранее. В реальном проекте мы настраиваем различные параметры в файле конфигурации. Но все также знают, что параметры конфигурации разных сред будут разными.Неизбежно, что из-за небрежности человека в файле конфигурации определенной среды будут отсутствовать некоторые ключевые параметры ненадежным способом. Если вы не используете этот метод для проверки, яму легко вызвать по особому сценарию. Но таким образом вы выполнили много проверок при запуске.Если параметры недействительны, проект не сможет запуститься, поэтому вы можете принять меры предосторожности, прежде чем это произойдет!
Controller
HelloDTO
@Data
public class HelloDTO {
@NotBlank
private String name;
@Min(0)
@Max(150)
private int age;
}
HelloController
@RestController
public class HelloController {
@RequestMapping("/controllerValid")
public String controllerValid(@RequestBody @Valid HelloDTO helloDTO) {
return "ok";
}
}
Параметр запроса
{
"name":"肥朝",
"age" : 151
}
Когда возникает исключение проверки
org.springframework.web.bind.MethodArgumentNotValidException
Service
HelloDTO
@Data
public class HelloDTO {
@NotBlank
private String name;
@Min(0)
@Max(150)
private int age;
}
AService
public interface AService {
int insertUser(HelloDTO helloDTO);
}
AServiceImpl
@Service
public class AServiceImpl implements AService {
@Autowired
private BService bService;
@Override
public int insertUser(HelloDTO helloDTO) {
return bService.insertUser(helloDTO);
}
}
BService
public interface BService {
int insertUser(@Valid HelloDTO helloDTO);
}
BServiceImpl
@Service
@Slf4j
@Validated
public class BServiceImpl implements BService {
@Override
public int insertUser(HelloDTO helloDTO) {
log.info("BService insertUser...");
return 0;
}
}
модульный тест
@RunWith(SpringRunner.class)
@SpringBootTest
public class AserviceTest {
@Autowired
private BService bService;
@Test
public void testInsertUser() throws Exception {
HelloDTO helloDTO = new HelloDTO();
bService.insertUser(helloDTO);
}
}
Информация об исключении проверки вывода:
javax.validation.ConstraintViolationException
Dubbo
Официальные документы Даббо написаны очень подробно, и адрес:Хироши Ватанабэ.apache.org/this-capable/docs/…
Функция проверки параметров реализована на основе JSR 303. Пользователям нужно только указать аннотацию проверки стандарта JSR 303 и реализовать проверку, объявив фильтр.
maven-зависимости
<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>
Пример
Пример выноски параметра
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 // 不允许为空
@Size(min = 1, max = 20) // 长度或大小范围
private String name;
@NotNull(groups = ValidationService.Save.class) // 保存时不允许为空,更新时允许为空 ,表示不更新该字段
@Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
private String email;
@Min(18) // 最小值
@Max(100) // 最大值
private int age;
@Past // 必须为一个过去的时间
private Date loginDate;
@Future // 必须为一个未来的时间
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;
}
}
Пример групповой проверки
public interface ValidationService { // 缺省可按服务接口区分验证场景,如:@NotNull(groups = ValidationService.class)
@interface Save{} // 与方法同名接口,首字母大写,用于区分验证场景,如:@NotNull(groups = ValidationService.Save.class),可选
void save(ValidationParameter parameter);
void update(ValidationParameter parameter);
}
Пример проверки ассоциации
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); // 直接对基本类型参数验证
}
настроить
Проверка параметров на стороне клиента
<dubbo:reference id="validationService" interface="org.apache.dubbo.examples.validation.api.ValidationService" validation="true" />
Проверка параметров на стороне сервера
<dubbo:service interface="org.apache.dubbo.examples.validation.api.ValidationService" ref="validationService" validation="true" />
Проверить информацию об исключении
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
ConstraintViolationException ve = (ConstraintViolationException) e.getCause(); // 里面嵌了一个ConstraintViolationException
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations(); // 可以拿到一个验证错误详细信息的集合
System.out.println(violations);
}
}
}
1. Так как2.1.0Версия начинает поддерживаться, как пользоваться можно посмотреть пример кода в проекте dubbo (GitHub.com/Apache/Inc U…)
2. Метод проверки может быть расширен.Чтобы узнать о методе расширения, обратитесь к расширению проверки в руководстве разработчика (Хироши Ватанабэ.apache.org/this-capable/docs/…)
Проверка класса инструмента
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) {
// 注意,在实际业务中
// 这里会根据violation进行参数拼接
// 然后进行自定义异常的抛出
}
}
}
модульный тест
@Test
public void testValidationUtils() throws Exception {
HelloDTO helloDTO = new HelloDTO();
ValidationUtils.validate(helloDTO);
}
Стук по доске
Приведенные выше примеры методов проверки по пяти аспектам основаны наhibernate-validate. Но если вы будете осторожны, вы обнаружите, что при поискеhibernate-validate, в основном только **controller**Эта схема, поэтому Фей Чао, состоит из нескольких слоев образцов кода, в основном охватывающих все ваши сцены.
Еще одна вещь, которую следует отметить, это то, что тип исключения проверки, выдаваемого уровнем контроллера,
org.springframework.web.bind.MethodArgumentNotValidException
Тип исключения проверки, выдаваемого сервисным уровнем:
javax.validation.ConstraintViolationException
При проверке метода класса инструмента необходимо получить обработку параметров, а затем настроить генерацию исключения. Поэтому при выполнении глобальных исключений нужно быть внимательным.
Конечно, этот метод проверки не только делает коэффициент проверки параметра
if (helloDTO.getAge() <= 0) {
//...
}
Много элегантности, но и поддержка自定义注解实现校验规则,国际化,分组校验Подождите, когда они будут использоваться в ваших конкретных проектах, вы можете посмотреть.
Конечно, есть много способов повысить надежность кода, но Фей Чао считает, что метод проверки параметров является одним из самых экономичных с точки зрения затрат и эффекта. код? Оставьте сообщение, чтобы сказать Фей Чао.