当前位置: 首页 > news >正文

网站icp 备案进度查询厦门百城建设有限公司网站

网站icp 备案进度查询,厦门百城建设有限公司网站,网站开发中用到的英文单词,中山市住房和城乡建设局网站一、前言 在 Spring 6.1 中#xff0c;有一个非常值得注意的重要改进——编程式验证器实现。Spring 长期以来一直通过注解支持声明式验证#xff0c;而 Spring 6.1 则通过提供专用的编程式验证方法引入了这一强大的增强功能。 编程式验证允许开发人员对验证过程进行细粒度控…一、前言 在 Spring 6.1 中有一个非常值得注意的重要改进——编程式验证器实现。Spring 长期以来一直通过注解支持声明式验证而 Spring 6.1 则通过提供专用的编程式验证方法引入了这一强大的增强功能。 编程式验证允许开发人员对验证过程进行细粒度控制实现动态和有条件的验证场景超越了声明式方法的能力。在本教程中我们将深入探讨实现编程式验证并将其与 Spring MVC 控制器无缝集成的细节。 二、声明式验证与编程式验证的区别 对于数据验证Spring 框架有两种主要方法声明式验证和编程式验证。 声明式验证Declarative validation通过域对象上的元数据或注解指定验证规则。Spring 利用 JavaBean Validation (JSR 380) 注释如 NotNull、Size 和 Pattern在类定义中直接声明验证约束。 Spring 会在数据绑定过程中自动触发验证例如在 Spring MVC 表单提交过程中。开发人员无需在代码中明确调用验证逻辑。 public class User {NotNullprivate String username;Size(min 6, max 20)private String password;// ... }另一方面“编程式验证Programmatic validation” 在代码中编写自定义验证逻辑通常使用 Spring 提供的 Validator 接口。这种方法可以实现更动态、更复杂的验证场景。 开发人员负责显式调用验证逻辑通常在服务层或控制器中进行。 public class UserValidator implements Validator {Overridepublic boolean supports(Class? clazz) {return User.class.isAssignableFrom(clazz);}Overridepublic void validate(Object target, Errors errors) {User user (User) target;// 自定义验证逻辑, 可以读取多个字段进行混合校验编程的方式灵活性大大增加} }三、何时使用程序化验证 在声明式验证和编程式验证之间做出选择取决于用例的具体要求。 声明式验证通常适用于比较简单的场景验证规则可以通过注释清晰地表达出来。声明式验证很方便也符合惯例即重于配置的原则。 程序化验证提供了更大的灵活性和控制力适用于超出声明式表达范围的复杂验证场景。当验证逻辑取决于动态条件或涉及多个字段之间的交互时程序化验证尤其有用。 我们可以将这两种方法结合起来使用。我们可以利用声明式验证的简洁性来处理常见的情况而在面对更复杂的要求时则采用编程式验证。 四、程序化验证器 API 简介 Spring 中的编程式验证器 API 的核心是允许创建自定义验证器类并定义仅靠注解可能无法轻松捕获的验证规则。 以下是创建自定义验证器对象的一般步骤。 创建一个实现 org.springframework.validation.Validator 接口的类。重载 supports() 方法以指定该验证器支持哪些类。实现 validate() 或 validateObject() 方法以定义实际的验证逻辑。使用 ValidationUtils.rejectIfEmpty() 或 ValidationUtils.rejectIfEmptyOrWhitespace() 方法以给定的错误代码拒绝给定字段。我们可以直接调用 Errors.rejectValue() 方法来添加其他类型的错误。 import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator;Component public class UserValidator implements Validator {Overridepublic boolean supports(Class? clazz) {return User.class.isAssignableFrom(clazz);}Overridepublic void validate(Object target, Errors errors) {User user (User) target;// 例如: 校验 username 不能为空ValidationUtils.rejectIfEmptyOrWhitespace(errors, username, field.required, Username must not be empty.);// 添加更多的自定义验证逻辑} }要使用自定义验证器我们可以将其注入 Controller 或 Service 等 Spring 组件或者直接将其实例化。然后我们调用验证方法传递要验证的对象和 Errors 对象以收集验证错误。 public class UserService {private Validator userValidator;public UserService(Validator userValidator) {this.userValidator userValidator;}public void someServiceMethod(User user) {Errors errors new BeanPropertyBindingResult(user, user);userValidator.validate(user, errors);if (errors.hasErrors()) {// 处理数据校验错误}} }五、初始化安装 5.1. Maven 配置 要使用编程式验证器我们需要 Spring Framework 6.1 或 Spring Boot 3.2因为这些是最低支持的版本。 parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.0/versionrelativePath/ /parent5.2. 领域对象 本教程的领域对象是雇员Employee 和部门Department对象。我们不会创建复杂的结构因此可以专注于核心概念。 Employee.java package demo.customValidator.model;Data Builder public class Employee {Long id;String firstName;String lastName;String email;boolean active;Department department; }Department.java package demo.customValidator.model;Data Builder public class Department {Long id;String name;boolean active; }六、 实现程序化验证器 以下 EmployeeValidator 类实现了 org.springframework.validation.Validator 接口并实现了必要的方法。它将根据需要在 Employee 字段中添加验证规则。 package demo.customValidator.validator;import demo.customValidator.model.Employee; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator;public class EmployeeValidator implements Validator {Overridepublic boolean supports(Class? clazz) {return Employee.class.isAssignableFrom(clazz);}Overridepublic void validate(Object target, Errors errors) {ValidationUtils.rejectIfEmpty(errors, id, ValidationErrorCodes.ERROR_CODE_EMPTY);ValidationUtils.rejectIfEmptyOrWhitespace(errors, firstName, First name cannot be empty);ValidationUtils.rejectIfEmptyOrWhitespace(errors, lastName, Last name cannot be empty);ValidationUtils.rejectIfEmptyOrWhitespace(errors, email, Email cannot be empty);Employee employee (Employee) target;if (employee.getFirstName() ! null employee.getFirstName().length() 3) {errors.rejectValue(firstName, First name must be greater than 2 characters);}if (employee.getLastName() ! null employee.getLastName().length() 3) {errors.rejectValue(lastName, Last name must be greater than 3 characters);}} }同样我们为 Department 类定义了验证器。如有必要您可以添加更复杂的验证规则。 package demo.customValidator.model.validation;import demo.customValidator.model.Department; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator;public class DepartmentValidator implements Validator {Overridepublic boolean supports(Class? clazz) {return Department.class.equals(clazz);}Overridepublic void validate(Object target, Errors errors) {ValidationUtils.rejectIfEmpty(errors, id, ValidationErrorCodes.ERROR_CODE_EMPTY);ValidationUtils.rejectIfEmptyOrWhitespace(errors, name, Department name cannot be empty);Department department (Department) target;if(department.getName() ! null department.getName().length() 3) {errors.rejectValue(name, Department name must be greater than 3 characters);}} }现在我们可以验证 Employee 和 Department 对象的实例如下所示 Employee employee Employee.builder().id(2L).build(); //Aurowire if needed EmployeeValidator employeeValidator new EmployeeValidator();Errors errors new BeanPropertyBindingResult(employee, employee); employeeValidator.validate(employee, errors);if (!errors.hasErrors()) {System.out.println(Object is valid); } else {for (FieldError error : errors.getFieldErrors()) {System.out.println(error.getCode());} }程序输出 First name cannot be empty Last name cannot be empty Email cannot be emptyDepartment 对象也可以进行类似的验证。 七、链式多个验证器 在上述自定义验证器中如果我们验证了雇员对象那么 API 将不会验证部门对象。理想情况下在验证特定对象时应针对所有关联对象执行验证。 程序化验证 API 允许调用其他验证器汇总所有错误最后返回结果。使用 ValidationUtils.invokeValidator() 方法可以实现这一功能如下所示 public class EmployeeValidator implements Validator {DepartmentValidator departmentValidator;public EmployeeValidator(DepartmentValidator departmentValidator) {if (departmentValidator null) {throw new IllegalArgumentException(The supplied Validator is null.);}if (!departmentValidator.supports(Department.class)) {throw new IllegalArgumentException(The supplied Validator must support the Department instances.);}this.departmentValidator departmentValidator;}Overridepublic void validate(Object target, Errors errors) {//...try {errors.pushNestedPath(department);ValidationUtils.invokeValidator(this.departmentValidator, employee.getDepartment(), errors);} finally {errors.popNestedPath();}} }pushNestedPath() 方法允许为子对象设置临时嵌套路径。在上例中当对部门对象进行验证时路径被设置为 employee.department。在调用 pushNestedPath() 方法之前popNestedPath() 方法会将路径重置为原始路径。在上例中它再次将路径重置为 employee。 现在当我们验证 Employee 对象时也可以看到 Department 对象的验证错误。 Department department Department.builder().id(1L).build(); Employee employee Employee.builder().id(2L).department(department).build();EmployeeValidator employeeValidator new EmployeeValidator(new DepartmentValidator());Errors errors new BeanPropertyBindingResult(employee, employee); employeeValidator.validate(employee, errors);if (!errors.hasErrors()) {System.out.println(Object is valid); } else {for (FieldError error : errors.getFieldErrors()) {System.out.println(error.getField());System.out.println(error.getCode());} }程序输出 firstName First name cannot be emptylastName Last name cannot be emptyemail Email cannot be emptydepartment.name Department name cannot be empty注意打印出来的字段名称是 department.name。由于使用了 pushNestedPath() 方法所以添加了 department. 前缀。 八、使用带消息解析功能的 MessageSource 使用硬编码的消息并不是一个好主意因此我们可以将消息添加到资源文件如 messages.properties中然后使用 MessageSource.getMessage() 将消息解析为所需的本地语言从而进一步改进此代码。 例如让我们在资源文件中添加以下消息 error.field.empty{0} cannot be empty error.field.size{0} must be between 3 and 20为了统一访问请在常量文件中添加以下代码。请注意这些错误代码是在自定义验证器实现中添加的。 public class ValidationErrorCodes {public static String ERROR_CODE_EMPTY error.field.empty;public static String ERROR_CODE_SIZE error.field.size; }现在当我们解析信息时就会得到属性文件的信息。 MessageSource messageSource;//...if (!errors.hasErrors()) {System.out.println(Object is valid); } else {for (FieldError error : errors.getFieldErrors()) {System.out.println(error.getCode());System.out.println(messageSource.getMessage(error.getCode(), new Object[]{error.getField()}, Locale.ENGLISH));} }程序输出 error.field.empty firstName cannot be emptyerror.field.empty lastName cannot be emptyerror.field.empty email cannot be emptyerror.field.empty department.name cannot be empty九、将编程式验证器与 Spring MVC/WebFlux 控制器集成 将编程式验证器与 Spring MVC 控制器集成包括将编程式验证器注入控制器、在 Spring 上下文中配置它们以及利用 Valid 和 BindingResult 等注解简化验证。 令人欣慰的是这种集成还能解决 Ajax 表单提交和控制器单元测试问题。 下面是一个使用我们在前面章节中创建的 EmployeeValidator 对象的 Spring MVC 控制器的简化示例。 import demo.app.customValidator.model.Employee; import demo.app.customValidator.model.validation.DepartmentValidator; import demo.app.customValidator.model.validation.EmployeeValidator; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*;Controller RequestMapping(/employees) public class EmployeeController {InitBinderprotected void initBinder(WebDataBinder binder) {// 注入 编程式验证器binder.setValidator(new EmployeeValidator(new DepartmentValidator()));}GetMapping(/registration)public String showRegistrationForm(Model model) {model.addAttribute(employee, Employee.builder().build());return employee-registration-form;}PostMapping(/processRegistration)public String processRegistration(Validated ModelAttribute(employee) Employee employee,BindingResult bindingResult) {if (bindingResult.hasErrors()) {return employee-registration-form;}// 处理成功通过数据校验后表单的逻辑// 通常涉及数据库操作、身份验证等。return employee-registration-confirmation; // 重定向至成功页面} }之后当表单提交时可以使用 ${#fields.hasErrors(*)} 表达式在视图中显示验证错误。 在下面的示例中我们在两个地方显示验证错误即在表单顶部的列表中显示所有错误然后显示单个字段的错误。请根据自己的要求定制代码。 !DOCTYPE html html langen xmlns:thhttp://www.thymeleaf.org headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleEmployee Registration/title /head bodyh2Employee Registration Form/h2!-- Employee Registration Form -- form action./processRegistration methodpost th:object${employee}!-- Display validation errors, if any --div th:if${#fields.hasErrors(*)}div stylecolor: red;p th:eacherror : ${#fields.errors(*)} th:text${error}/p/div/div!-- Employee ID (assuming its a hidden field for registration) --input typehidden th:field*{id} /!-- Employee First Name --label forfirstNameFirst Name:/labelinput typetext idfirstName th:field*{firstName} required /span th:if${#fields.hasErrors(firstName)} th:text#{error.field.size}/spanbr/!-- Employee Last Name --label forlastNameLast Name:/labelinput typetext idlastName th:field*{lastName} required /span th:if${#fields.hasErrors(lastName)} th:text#{error.field.size}/spanbr/!-- Employee Email --label foremailEmail:/labelinput typeemail idemail th:field*{email} required /span th:if${#fields.hasErrors(email)} th:text#{error.field.size}/spanbr/!-- Employee Active Status --label foractiveActive:/labelinput typecheckbox idactive th:field*{active} /br/!-- Department Information --h3Department:/h3label fordepartment.nameDepartment Name:/labelinput typetext iddepartment.name th:field*{department.name} required /span th:if${#fields.hasErrors(department.name)} th:text#{error.field.size}/spanbr/!-- Submit Button --button typesubmitRegister/button/form/body /html当我们运行应用程序并提交无效表单时会出现如图所示的错误 十、单元测试编程式验证器 我们可以将自定义验证器作为模拟依赖关系或单个测试对象进行测试。下面的 JUnit 测试用例将测试 EmployeeValidator。 我们编写了两个非常简单的基本测试供快速参考您也可以根据自己的需求编写更多测试。 import demo.app.customValidator.model.Department; import demo.app.customValidator.model.Employee; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors;public class TestEmployeeValidator {static EmployeeValidator employeeValidator;BeforeAllstatic void setup() {employeeValidator new EmployeeValidator(new DepartmentValidator());}Testvoid validate_ValidInput_NoErrors() {// Set up a valid userEmployee employee Employee.builder().id(1L).firstName(Lokesh).lastName(Gupta).email(adminhowtodoinjava.com).department(Department.builder().id(2L).name(Finance).build()).build();Errors errors new BeanPropertyBindingResult(employee, employee);employeeValidator.validate(employee, errors);Assertions.assertFalse(errors.hasErrors());}Testvoid validate_InvalidInput_HasErrors() {// Set up a valid userEmployee employee Employee.builder().id(1L).firstName(A).lastName(B).email(C).department(Department.builder().id(2L).name(HR).build()).build();Errors errors new BeanPropertyBindingResult(employee, employee);employeeValidator.validate(employee, errors);Assertions.assertTrue(errors.hasErrors());Assertions.assertEquals(3, errors.getErrorCount());} }最佳做法是确保测试涵盖边缘情况和边界条件。这包括输入处于允许的最小值或最大值的情况。 十一、结论 在本教程中我们通过示例探讨了 Spring 6.1 Programmatic Validator API 及其实施指南。程序化验证允许开发人员对验证过程进行细粒度控制。 我们讨论了如何创建和使用自定义验证器类并将其与 Spring MVC 控制器集成。我们学习了如何使用消息解析随后还讨论了如何测试这些验证器以实现更强大的编码实践。 代码地址programmatic-validator
http://www.sadfv.cn/news/90690/

相关文章:

  • 做的网站在百度上搜不出来的兄弟网站制作
  • 生成静态网站怎么建站网站
  • 红衫中国网站建设wordpress+插件+h5
  • 龙华新区网站建设wordpress如何修改字体大小
  • 瑞安建设公司网站软文广告经典案例分析
  • 泰州整站优化泰安民生网
  • 巩义网站优化凡科网站建设之后怎么删除
  • 网站建设 贸易福州产品网页制作的公司
  • 哪个网站可以做店招店标轮播html5网站引导页
  • 济南专业制作网站网站如何做标题优化
  • 动易学校网站管理系统 漏洞重庆手机网站推广资料
  • 免费网站下载直播软件广州市城乡建设局
  • 徐州做网站建设上海市工程建设交易中心网站
  • h网站模版seo外包大型公司
  • 网站后台怎么上传图片wordpress 悬停遮罩
  • 做网站要买什么类型云空间网站建设费用分几年摊销
  • 邢台网站改版制作公司百度seo效果怎么样
  • 网站策划设计建设免费虚拟主机网站源码
  • html5手机网站开发视频教程外包服务平台
  • 怎么看网站的访问量螺蛳粉营销策划方案
  • 如何备案成企业网站wordpress最详细的教程视频教程
  • asp.net+h5网站开发牛商网网站做seo好么
  • 静安网站开发seo关键词是什么
  • 网站建设中 尽情期待网站开发word
  • 做的好的网站着陆页学网站开发在大学
  • 网站开发认证考试外国做家具的网站
  • 长沙市宁乡县建设局网站打开汽车之家网页版
  • asp连接数据库做登录网站完整下载为什么wordpress在ie打开很慢
  • 网站开发 案例从化哪里做网站好
  • 阿里云网站简单建设国外的服务器