首页 > 其他分享 >Spring自定义数据校验并实现国际化功能

Spring自定义数据校验并实现国际化功能

时间:2023-11-05 17:37:09浏览次数:48  
标签:return 定义数据 Mobile Spring 校验 messageSource public String

通常,当我们需要验证用户输入时,Spring MVC提供标准的预定义验证器。我们会引入spring-boot-starter-validation依赖来实现数据校验功能。

但是,当我们需要验证特定类型的输入时,我们就需要创建自己的自定义校验逻辑。这里我们取一个相对简单的校验手机号码的功能来实现。

为了校验手机号码,我们需要引入谷歌的 libphonenumber依赖Spring的和spring-boot-starter-validation:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-validation</artifactId> 
</dependency>
<dependency> 
    <groupId>com.googlecode.libphonenumber</groupId> 
    <artifactId>libphonenumber</artifactId> 
</dependency>

创建注解

我们创建一个新的@interface来创建注解:

/**
 * 手机号校验
 */
@Documented
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(List.class)
@Constraint(validatedBy = {MobileValidator.class})
public @interface Mobile {

    /**
     * 错误消息
     *
     * @return 错误消息
     */
    String message() default "{com.demo.validation.constraints.Mobile.message}";

    /**
     * 分组
     *
     * @return 分组
     */
    Class<?>[] groups() default {};

    /**
     * payload
     *
     * @return payload
     */
    Class<? extends Payload>[] payload() default {};

    /**
     * 默认地域,用于识别手机号
     *
     * @return 默认地域
     */
    String defaultRegion() default "CN";

    /**
     * 允许的地域列表
     *
     * @return 允许的地域列表
     */
    String[] regions() default {"CN"};

    /**
     * 列表
     */
    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @Documented
    public @interface List {

        /**
         * value
         *
         * @return value
         */
        Mobile[] value();
    }
}

使用@Constraint注解,我们定义了实际用来处理验证字段的类。message()是显示在用户交互界面中的错误消息。最后,附加代码主要是符合Spring标准的样板代码。

这里的message()如果你不需要国际化功能,你也可以直接写死,比如“手机号不合法”之类的,但此处我们还想实现国际化功能,还是需要设置成多语言信息的形式。

创建验证类

现在让我们创建一个验证器类来执行我们的验证规则:

/**
 * 手机号校验
 */
public class MobileValidator implements ConstraintValidator<Mobile, String> {

    private String defaultRegion;

    private String[] regions;

    @Override
    public void initialize(Mobile constraintAnnotation) {
        defaultRegion = constraintAnnotation.defaultRegion();
        regions = constraintAnnotation.regions();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        PhoneNumberUtil phoneUtils = PhoneNumberUtil.getInstance();
        try {
            PhoneNumber phoneNumber = phoneUtils.parse(value, defaultRegion);
            String regionCode = phoneUtils.getRegionCodeForCountryCode(phoneNumber.getCountryCode());
            boolean parseRet = Arrays.stream(regions).anyMatch(item -> item.equalsIgnoreCase(regionCode));
            if (!parseRet) {
                return false;
            }
            return phoneUtils.isValidNumber(phoneNumber);
        } catch (NumberParseException e) {
            return false;
        }
    }
}

验证类主要实现了ConstraintValidator接口,还必须实现isValid方法;我们正是在这个方法中定义了验证规则。我们这里简单的借助libphonenumber依赖来帮我们实现手机号的校验。

而在initialize中我们主要做了注解参数的处理,这里defaultRegion主要设置默认的号码地域,比如这里是中国大陆CN,另外一个regions主要用于设置校验哪些地区的手机号。

创建多语言文件

为了实现国际化功能,我们还需要添加多语言文件,比如我们建在 resources/com/demo/validator/ValidationMessages目录下,我们新建对应的多语言文件:

  • ValidationMessages.properties
com.demo.validation.constraints.Mobile.message=必须为格式规范的手机号
  • ValidationMessages_en.properties
com.demo.validation.constraints.Mobile.message=must be a well-formed phone number
  • ValidationMessages_zh_CN.properties
com.demo.validation.constraints.Mobile.message=必须为格式规范的手机号
  • ValidationMessages_zh_TW.properties
com.demo.validation.constraints.Mobile.message=必須是形式完整的電話號碼

引入多语言文件

/**
 * 参数校验自动配置
 */
@Configuration
@ConditionalOnClass(ExecutableValidator.class)
@AutoConfigureBefore(ValidationAutoConfiguration.class)
public class ValidationConfiguration {

    /**
     * 校验factory
     *
     * @param messageSource 错误信息
     * @return LocalValidatorFactoryBean
     */
    @Bean
    @ConditionalOnMissingBean
    public LocalValidatorFactoryBean localValidatorFactoryBean(@Qualifier("customValidationMessageSource") MessageSource messageSource) {
        LocalValidatorFactoryBean localValidator = new LocalValidatorFactoryBean();
        localValidator.setValidationMessageSource(messageSource);
        return localValidator;
    }

    /**
     * 参数校验的错误信息源
     *
     * @return MessageSource
     */
    @Bean("customValidationMessageSource")
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.addBasenames("classpath:org.hibernate.validator.ValidationMessages",
                "classpath:com/demo/validator/ValidationMessages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}

这里主要有几点需要关注:

  • 我们使用@AutoConfigureBefore(ValidationAutoConfiguration.class)要求这个配置类在ValidationAutoConfiguration之前装配,避免LocalValidatorFactoryBean已经存在造成冲突。

  • 通过创建自定义的MessageSource,添加了hibernate的多语言文件,同时把我们自己的多语言文件也添加进去了。

  • LocalValidatorFactoryBean的ValidationMessageSource设置为我们自定义的MessageSource

使用

如果要对数据进行校验,我们只需要在字段上添加注解,然后使用@Valid或者@Validated对数据校验即可:

@Mobile
private String phone;
@Controller
public class ValidatedPhoneController {
 
    @PostMapping("/addValidatePhone")
    public String submitForm(@Valid ValidatedPhone validatedPhone) {
    }   
}

原文地址

原文首发于Spring自定义数据校验并实现国际化功能

标签:return,定义数据,Mobile,Spring,校验,messageSource,public,String
From: https://www.cnblogs.com/JefferyWang/p/spring-custom-validation.html

相关文章

  • springboot入门
    两年没写了。。连右下的小人都没了。得开始新一阶段的学习了。先从学习springboot及其前置内容开始学习。然后简单复习一下vue框架。idea在创建maven的springboot工程时自动下了个依赖,尽量选择版本低一点的。。适配java8不容易出问题。一旦出问题了多重建项目就会重新下springboo......
  • SpringBoot 基础知识
    ​#SpringBoot#​‍本文基于SpringBoot2.0最新稳定版2.7.6;目前SpringBoot3.0已经发布,后续会体验新版新特性。官网:SpringBoot‍SpringBoot程序的优点起步依赖(简化依赖配置)自动配置(简化常用工程相关配置)辅助功能(内置服务器,.....)快速上手SpringBoot工程联网......
  • SpringBoot图书管理系统运行教程
    @文章目录目录1、前期必备1.1、所需软件版本说明1.2、下载源码1.3、下载开发工具1.4、下载JDK并配置环境变量1.5、安装数据库和数据库管理工具1.6、安装配置Maven2、将SQL文件导入到数据库2.1、新建MySQL连接2.2、新建数据库并导入SQL3、IDEA配置Maven环境4、IDEA安装Lombok插件5......
  • 后端添加校验规则
    添加校验规则防止数据库中的数据混乱;1..NETCore中内置了对数据校验的支持,在System.ComponentModel.DataAnnotations这个命名空间下,比如【Required】【EmailAddress】【RegularExpresion】长度限制minlength等;-2.内置的校验机制问题,校验规则人都是和模型类耦合在......
  • spring 事务
    一、事务简介1、事务作用:在数据层保障一系列的数据库操作同步成功同步失败2、Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败,其是使用JDBC的事务管理器实现的,如果数据层使用的是JDBC,则可以使用Spring事务其是通过内部接口和实现类实现的/......
  • spring boot集成elk 7.9.1
    一、组件安装es第一次运行es dockerrun-d\ --nameelasticsearch\ --envES_JAVA_OPTS=-"Xms1024m-Xmx1024m"\ --env"discovery.type=single-node"\ --envTZ=Asia/Shanghai\ -p9200:9200/tcp\ -p9300:9300/tcp\ --restart=always\ ......
  • 基于Spring Boot的图书管理系统
    系统关键词图书管理、图书类别、图书借阅、图书归还、图书丢失、图书续借、借还统计、图书统计技术栈后端技术栈:SpringBoot、Shiro、MySQL、Redis、MyBatis-Plus、WebSocket前端技术栈:LayUI、Thymeleaf、jQuery、FontAwesome、WangEditor、zTree功能模块功能截图登......
  • SpringBoot系列之MyBatis Plus自动填充实现
    系列博客专栏:SpringBoot2.0系列博客专栏开发环境JDK1.8SpringBoot2.2.1Maven3.2+Mysql5.7.36开发工具IntelliJIDEAsmartGit项目场景在项目中经常会遇到需要自动填充数据的情况,比如新增一个DO类,里面可能会有id、create_time、modify_time、create_u......
  • 基于springboot的计算机毕业设计帮写
    主要内容:基于springboot的毕业作品设计、基于VUE的、基于安卓APP、基于微信小程序的、原创、设计、毕设、哪里、找我、添加me企鹅numberisone--zero-three-two-three-seven-one-two-one步骤:1.毕设第一步,首先是选题尽量选择新颖的设计题目;2.确定系统功能,完成开题报告;3.编码实......
  • day128-spring boot依赖管理特性与自动配置特性
    springboot依赖管理特性父项目做依赖管理依赖管理:<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version></parent>   其父项目:<......