hibernate-validator改进校验框架validator v0.4使用

来讲一下“hibernate-validator改进校验框架validator v0.4使用”的完整攻略。

什么是Hibernate-Validator?

Hibernate-Validator 是一款校验框架。这个框架的初衷是为了在 JavaBean 层面上提供一套统一、可重用的验证机制,使得我们在对 JavaBean 进行数据验证时能够更加方便、快捷、灵活。

为什么要改进校验框架?

虽然Hibernate-Validator 是一款很强大的校验框架,但是它并不完美。使用过程中也会存在一些问题,比如:

  • 对于一些非基本类型的校验,在实现上有些复杂。
  • 使用起来不是很方便,需要大量的注解。

所以,在实际的开发过程中,我们可能需要对 Hibernate-Validator 进行一些改进,以使其更加适合我们的实际需求。

改进

改进主要有两个方面,一个是简化校验逻辑,减少注解的使用;另一个是对于复杂类型的校验能够更加便捷。

简化校验逻辑

我们可以通过自定义注解,来简化校验逻辑。假设我们需要校验一个User对象,其中包含一个名字字段,这个字段的长度应该在1到10之间。原来的写法可能是这样:

public class User {
    @Size(min = 1, max = 10)
    private String name;
    ...
}

这里我们使用了 @Size 注解来进行校验。如果我们要在其他地方也需要对这个长度做校验,就需要再次在其他地方加上这个注解。代码冗余。

我们可以自定义注解,比如:

@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = { UserNameValidator.class })
public @interface UserName {
    String message() default "名字长度不正确";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

然后使用这个注解来替换原来的 @Size 注解:

public class User {
    @UserName
    private String name;
    ...
}

这样,我们就可以将校验逻辑定义在一个地方,避免了代码重复。

对于复杂类型的校验能够更加便捷

使用 Hibernate-Validator 进行校验一个 List,原来的写法可能是这样:

public void validate(List<User> users) {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();
    for (User user : users) {
        Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
        // ...
    }
}

这里我们需要手动遍历List,将每个User对象拿出来进行校验。这种写法不仅代码量大,还不够优雅。

我们可以使用一个注解 @Valid,这个注解可以直接将List中的对象进行校验。代码大大简化:

public void validate(@Valid List<User> users) {
    // ...
}

这个注解下文中会再次提到。

两条示例

我们举两个例子来说明 Hibernate-Validator 的使用方法和对其进行改进的方法。

示例一:校验日期格式

在开发过程中,我们可能需要对日期格式进行校验。Hibernate-Validator 中提供了一个注解 @Past,可以用来检查一个日期是否在当前时间之前。但是在实际场景中我们可能需要使用自己定义的日期格式来进行校验。

首先,我们自定义一个注解 DatePattern:

@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = {DatePatternValidator.class})
public @interface DatePattern {

    String message() default "日期格式不正确";

    String pattern() default "yyyy-MM-dd";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({METHOD, FIELD, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    public @interface List {
        DatePattern[] value();
    }
}

其中这个注解有两个属性:message表示验证失败时的错误信息;pattern表示日期格式。

然后编写一个实现校验逻辑的validator:

public class DatePatternValidator implements ConstraintValidator<DatePattern, String> {

    private String pattern;

    @Override
    public void initialize(DatePattern constraintAnnotation) {
        pattern = constraintAnnotation.pattern();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        return TimeUtil.checkDateFormat(value.trim(), this.pattern);
    }
}

这里我们根据注解中的日期格式 pattern,使用 TimeUtil 工具类进行校验。TimeUtil.checkDateFormat() 的实现可以参考如下:

public static boolean checkDateFormat(String value, String format) {
    try {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setLenient(false);
        sdf.parse(value);
        return true;
    } catch (ParseException e) {
        return false;
    }
}

这样,我们就可以使用 @DatePattern 注解来校验日期格式了:

public class Order {

    @DatePattern(message = "日期格式不正确", pattern = "yyyy-MM-dd HH:mm:ss")
    private String createTime;

    // getter & setter
}

示例二:校验内嵌对象

Hibernate-Validator 可以直接对一个对象进行校验。但是如果这个对象中还包含了其它对象,或者是一个 List,我们还需要手动去遍历,对其内部进行校验。为了解决这个问题,我们可以使用 @Valid 注解。

假设我们有一个 User 对象,它包含了一个地址,地址中又包含了城市和省份信息:

public class User {

    private String name;

    @Valid
    private Address address;

    // getter & setter
}

public class Address {

    private String city;

    private String province;

    // getter & setter
}

对于嵌套的对象,我们只需要在字段上使用 @Valid 注解,然后就可以进行递归校验了。

Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);

这里我们使用了 Hibernate-Validator 提供的 validate 方法,这个方法内部会自动递归进行校验。

另外,如果我们要对一个 List 进行校验,也可以使用 @Valid 注解:

public class Order {

    @NotNull(message = "订单不能为空")
    @Size(min = 1, message = "订单至少包含一项")
    @Valid
    private List<OrderItem> orderItems;

    // getter & setter
}

这样,就可以对 Order 对象中的 orderItems 进行校验了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:hibernate-validator改进校验框架validator v0.4使用 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 使用Java将字符串在ISO-8859-1和UTF-8之间相互转换

    首先,我们需要了解一下ISO-8859-1和UTF-8。 ISO-8859-1是一种字符编码,能够表示大部分欧洲语言的字符。在ISO-8859-1中,每个字符占据一个字节,使用1个字节来表示一个字符。然而,ISO-8859-1不能表示非欧洲语言的字符,比如中文、日文等。 而UTF-8则是一种Unicode字符编码,能够表示世界上的所有字符。UTF-8使用1到…

    Java 2023年5月20日
    00
  • bootstrap 下拉多选框进行多选传值问题代码分析

    下面给出“bootstrap下拉多选框进行多选传值问题代码分析”的完整攻略。 1. 背景 在使用bootstrap开发Web应用时,经常会使用下拉多选框进行多选,但如何将所选的值传递给后端服务器,还是一个值得探讨的问题。 2. 问题 bootstrap的下拉多选框有一个data-selected-text-format属性,它可以控制选中的值的格式,如可以将…

    Java 2023年6月15日
    00
  • Java的Spring框架下RMI与quartz的调用方法

    Java的Spring框架下RMI与quartz的调用方法主要分为以下几个步骤: 首先需要在pom.xml文件中添加相应的依赖: <dependency> <groupId>org.springframework</groupId> <artifactId>spring-rmi</artifactId&g…

    Java 2023年5月19日
    00
  • SpringMVC 向jsp页面传递数据库读取到的值方法

    首先需要说明的是,SpringMVC向JSP页面传递数据库读取到的值的方法有很多种,这里介绍一种基本的方法。 控制层(Controller) 在控制层中我们需要注入一个由Service层封装好的Map对象,并将这个Map对象存入ModelAndView中,然后返回给View层(即JSP页面)。 示例: @Controller public class Use…

    Java 2023年5月26日
    00
  • jsp网页搜索结果中实现选中一行使其高亮

    要在jsp网页搜索结果中实现选中一行使其高亮,我们可以采用以下步骤: 添加CSS样式 我们需要添加一个CSS样式来定义高亮选中的样式,比如我们可以定义一个名为”selected”的样式: .selected { background-color: #ffffcc; } 编写Javascript代码 使用javascript代码,我们可以监听table中的tr…

    Java 2023年6月15日
    00
  • Springboot如何去掉URL后面的jsessionid

    要去掉Spring Boot应用程序中URL后的JSESSIONID,可以在servlet过滤器中进行配置,具体步骤如下: 创建一个过滤器类,并实现javax.servlet.Filter接口。 @Component public class JSessionIdFilter implements Filter { @Override public void…

    Java 2023年5月20日
    00
  • 什么是内存泄漏?

    以下是关于内存泄漏的完整使用攻略: 什么是内存泄漏? 内存泄漏是指程序在运行过程中,分配的内存空间没有被及时释放,导致内存空间的浪费和程序运行速度的下降。内存泄漏是一种常见的程序错误,如果不及时处理,会导致程序崩溃或者系统崩溃。 如何检测内存泄漏? 为了检测内存泄漏,可以使用一些工具来帮助我们检测程序中的内存泄漏。常用的工具包括: Valgrind:一款开源…

    Java 2023年5月12日
    00
  • 关于SQL注入绕过的一些知识点

    关于SQL注入绕过的知识点,这是一项非常复杂的话题,需要掌握的知识点比较多,下面我会给大家详细解析。 1.理解SQL注入的定义 我们首先需要清楚SQL注入是什么,顾名思义,SQL注入就是对网站中使用的SQL语句进行注入,从而达到非法获取数据或者控制网站的目的。这种攻击方式是因为开发者在编写代码的时候没有进行充分的输入验证而导致网站的漏洞造成的。 2. 理解S…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部