龙空技术网

28个验证注解,通过业务案例让你精通Java数据校验(收藏篇)

肖哥弹架构 177

前言:

目前朋友们对“java 数据校验”大致比较着重,咱们都需要了解一些“java 数据校验”的相关文章。那么小编也在网络上搜集了一些关于“java 数据校验””的相关文章,希望朋友们能喜欢,大家一起来学习一下吧!

在现代软件开发中,数据验证是确保应用程序健壮性和可靠性的关键环节。Java Bean Validation (JSR 380) 作为一个功能强大的规范,为我们提供了一套全面的注解工具集,这些注解能够帮助开发者在Java应用程序中以一种声明式的方式执行数据验证。从基本的非空验证到复杂的正则表达式匹配,JSR 380规范及其实现,如Hibernate Validator,都为我们提供了丰富的选项来满足各种验证需求。

肖哥弹架构 跟大家“弹弹” 常用框架注解应用,需要代码关注

欢迎 点赞,关注,评论。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章一个项目代码讲清楚DO/PO/BO/AO/E/DTO/DAO/ POJO/VO@NotNull1.1 注解作用介绍

@NotNull 注解用于确保被注解的字段不为 null。这在需要强制字段必须有值的情况下非常有用,例如,用户实体的用户名或电子邮件字段。

1.2 注解属性介绍message: 指定验证失败时返回的自定义错误消息。groups: 指定此约束所属的验证组,用于在不同的场景下应用不同的验证规则。payload: 允许注解携带额外的元数据,这些元数据可以在验证失败时由验证器使用。1.3 注解业务案例

public class User {    @NotNull(message = "用户名不能为空")    private String username;    // 其他用户属性...}public class User {    @NotNull(message = "用户名不能为空", groups = RegistrationChecks.class, payload = ErrorPayloads.class)    private String username;    // 用户名是用户身份的唯一标识,注册时必须填写。    // groups属性定义了此验证属于RegistrationChecks组,可用于部分验证场景。    // payload属性可用于携带额外的元数据,供验证器使用。}
@NotBlank2.1 注解作用介绍

@NotBlank 注解除了确保字符串不为 null 外,还检查字符串至少有一个非空白字符。这适用于需要文本输入的字段,如用户评论或表单提交。

2.2 注解属性介绍message: 自定义验证失败时的错误消息。groups: 指定验证组。payload: 额外数据。trim: 布尔值,默认为 true,指示是否在验证前去除字符串两端的空白字符。2.3 注解业务案例

public class Comment {    @NotBlank(message = "评论内容不能为空", trim = true)    private String content;    // 其他评论属性...}public class Comment {    @NotBlank(message = "评论内容不能为空", trim = true, groups = CommentChecks.class, payload = ErrorPayloads.class)    private String content;    // 评论内容必须填写,trim=true表示在验证前去除两端空白字符。    // groups属性定义了此验证属于CommentChecks组。}
@NotEmpty3.1 注解作用介绍

@NotEmpty 注解用于验证字符串、集合或数组不为 null 且至少有一个元素(对于集合和数组)或至少有一个非空白字符(对于字符串)。

3.2 注解属性介绍message: 自定义验证失败时的错误消息。groups: 指定验证组。payload: 额外数据。3.3 注解业务案例

public class Message {    @NotEmpty(message = "消息内容不能为空")    private String text;    // 其他消息属性...}public class Message {    @NotEmpty(message = "消息内容不能为空", groups = MessageChecks.class, payload = ErrorPayloads.class)    private String text;    // 消息文本不能为空,适用于消息发送场景。}
@Size4.1 注解作用介绍

@Size 注解用于验证字符串、集合、数组或Map的大小是否在指定的范围内。

4.2 注解属性介绍min: 指定最小大小。max: 指定最大大小。message: 自定义验证失败时的错误消息。groups: 指定验证组。payload: 额外数据。4.3 注解业务案例

public class Book {    @Size(min = 1, max = 100, message = "书名长度必须在1到100个字符之间")    private String title;    // 其他书籍属性...}public class Book {    @Size(min = 1, max = 100, message = "书名长度必须在1到100个字符之间", groups = BookChecks.class, payload = ErrorPayloads.class)    private String title;    // 书名长度限制,适用于图书管理系统。}
@Past5.1 注解作用介绍

@Past 注解用于验证日期类型的字段是否表示过去的日期。

5.2 注解属性介绍message: 自定义验证失败时的错误消息。5.3 注解业务案例

import java.time.LocalDate;public class Event {    @Past(message = "事件日期必须是过去的日期")    private LocalDate eventDate;    // 其他事件属性...}import java.time.LocalDate;public class Event {    @Past(message = "事件日期必须是过去的日期", groups = EventChecks.class, payload = ErrorPayloads.class)    private LocalDate eventDate;    // 事件日期应为过去日期,适用于历史事件记录。}
@Future6.1 注解作用介绍

@Future 注解用于验证日期类型的字段是否表示未来的日期。

6.2 注解属性介绍message: 自定义验证失败时的错误消息。6.3 注解业务案例

public class Delivery {    @Future(message = "预计送达日期必须是未来的日期")    private LocalDate expectedDeliveryDate;    // 其他送达属性...}public class Delivery {    @Future(message = "预计送达日期必须是未来的日期", groups = DeliveryChecks.class, payload = ErrorPayloads.class)    private LocalDate expectedDeliveryDate;    // 预计送达日期应为未来日期,适用于订单处理系统。}
@Pattern7.1 注解作用介绍

@Pattern 注解用于验证字符串是否与指定的正则表达式匹配。

7.2 注解属性介绍regexp: 指定的正则表达式。message: 自定义验证失败时的错误消息。flags: 正则表达式的匹配标志。7.3 注解业务案例

public class UserRegistration {    @Pattern(regexp = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",              message = "电子邮箱格式不正确" flags = {Pattern.Flag.CASE_INSENSITIVE})    private String email;    // 其他注册属性...}public class UserRegistration {    @Pattern(regexp = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$",               message = "电子邮箱格式不正确", flags = {Pattern.Flag.CASE_INSENSITIVE}, groups = RegistrationChecks.class, payload = ErrorPayloads.class)    private String email;    // 电子邮箱格式验证,适用于用户注册表单。}
@Min8.1 注解作用介绍

@Min 注解用于验证数值类型的字段是否大于或等于指定的最小值。

8.2 注解属性介绍value: 指定的最小值。message: 自定义验证失败时的错误消息。8.3 注解业务案例

public class Product {    @Min(value = 1, message = "购买数量不能少于1")    private int quantity;    // 其他产品属性...}public class Product {    @Min(value = 1, message = "购买数量不能少于1", groups = ProductChecks.class, payload = ErrorPayloads.class)    private int quantity;    // 购买数量验证,适用于购物车系统。}
@Max9.1 注解作用介绍

@Max 注解用于验证数值类型的字段是否小于或等于指定的最大值。

9.2 注解属性介绍value: 指定的最大值。message: 自定义验证失败时的错误消息。9.3 注解业务案例

public class Product {    @Max(value = 100, message = "库存数量不能超过100")    private int stock;    // 其他产品属性...}public class Product {    @Max(value = 100, message = "库存数量不能超过100", groups = StockChecks.class, payload = ErrorPayloads.class)    private int stock;    // 库存数量验证,适用于库存管理系统。}
@DecimalMin10.1 注解作用介绍

@DecimalMin 注解用于验证 BigDecimal 或包装的数值类型字段是否大于或等于指定的十进制最小值。

10.2 注解属性介绍value: 指定的十进制最小值。inclusive: 布尔值,指示是否包含指定的边界值(默认为 true)。message: 自定义验证失败时的错误消息。10.3 注解业务案例

public class Price {    @DecimalMin(value = "0.00", inclusive = true, message = "价格必须非负")    private BigDecimal value;    // 其他价格属性...}public class Price {    @DecimalMin(value = "0.00", inclusive = true, message = "价格必须非负", groups = PriceChecks.class, payload = ErrorPayloads.class)    private BigDecimal value;    // 价格必须为非负值,适用于财务管理系统。}
@DecimalMax11.1 注解作用介绍

@DecimalMax 注解用于验证 BigDecimal 或包装的数值类型字段是否小于或等于指定的十进制最大值。

11.2 注解属性介绍value: 指定的十进制最小值。inclusive: 布尔值,指示是否包含指定的边界值(默认为 true)。message: 自定义验证失败时的错误消息。11.3 注解业务案例

public class Price {    @DecimalMax(value = "1000.00", inclusive = true, message = "价格不能超过1000")    private BigDecimal value;    // 其他价格属性...}public class Price {    @DecimalMax(value = "1000.00", inclusive = true, message = "价格不能超过1000", groups = PriceChecks.class, payload = ErrorPayloads.class)    private BigDecimal value;    // 价格上限验证,适用于定价策略。}
@Email12.1 注解作用介绍

@Email 注解用于验证字符串字段是否为有效的电子邮件地址。

12.2 注解属性介绍message: 自定义验证失败时的错误消息。regexp: 用于验证电子邮件地址的正则表达式(可选)。12.3 注解业务案例

public class User {    @Email(message = "电子邮件地址无效")    private String email;    // 其他用户属性...}public class User {    @Email(message = "电子邮件地址无效", regexp = "^.+@.+\\..+$", groups = UserChecks.class, payload = ErrorPayloads.class)    private String email;    // 电子邮箱地址验证,适用于用户信息管理。}
@Valid13.1 注解作用介绍

@Valid 注解用于递归地对关联的对象或集合进行验证。

13.2 注解属性介绍groups: 指定嵌套对象应使用的验证组。payload: 额外数据。13.3 注解业务案例

public class Order {    @Valid    private User user;    @Valid    private List<OrderItem> items;    // 其他订单属性...}public class Order {    @Valid(groups = OrderChecks.class, payload = ErrorPayloads.class)    private User customer;    // 递归验证用户信息,适用于订单处理。}

## @Positive

14.1 注解作用介绍

@Positive 注解用于验证数值类型的字段是否严格大于 0。

14.2 注解属性介绍message: 自定义验证失败时的错误消息。groups: 指定验证组。payload: 额外数据。14.3 注解业务案例

public class Account {    @Positive(message = "账户余额必须为正数")    private BigDecimal balance;    // 其他账户属性...}public class Account {    @Positive(message = "账户余额必须为正数", groups = AccountChecks.class, payload = ErrorPayloads.class)    private BigDecimal balance;    // 账户余额验证,适用于银行账户管理。}
@PositiveOrZero15.1 注解作用介绍

@PositiveOrZero 注解用于验证数值类型的字段是否大于或等于 0。

15.2 注解属性介绍message: 自定义验证失败时的错误消息。groups: 指定验证组。payload: 额外数据。15.3 注解业务案例

public class Account {    @PositiveOrZero(message = "账户余额不能为负数")    private BigDecimal balance;    // 其他账户属性...}public class Account {    @PositiveOrZero(message = "账户余额不能为负数", groups = AccountChecks.class, payload = ErrorPayloads.class)    private BigDecimal balance;    // 账户余额验证,确保余额非负。}
@Negative16.1 注解作用介绍

@Negative 注解用于验证数值类型的字段是否严格小于 0。

16.2 注解属性介绍message: 自定义验证失败时的错误消息。groups: 指定验证组。payload: 额外数据。16.3 注解业务案例

public class Debt {    @Negative(message = "债务金额必须为负数")    private BigDecimal amount;    // 其他债务属性...}public class Debt {    @Negative(message = "债务金额必须为负数", groups = DebtChecks.class, payload = ErrorPayloads.class)    private BigDecimal amount;    // 债务金额验证,适用于债务管理。}
@NegativeOrZero17.1 注解作用介绍

@NegativeOrZero 注解用于验证数值类型的字段是否小于或等于 0。

17.2 注解属性介绍message: 自定义验证失败时的错误消息。groups: 指定验证组。payload: 额外数据。17.3 注解业务案例

public class Debt {    @NegativeOrZero(message = "债务金额不能为正数")    private BigDecimal amount;    // 其他债务属性...}public class Debt {    @NegativeOrZero(message = "债务金额不能为正数", groups = DebtChecks.class, payload = ErrorPayloads.class)    private BigDecimal amount;    // 债务金额验证,确保债务非正。}
@Digits18.1 注解作用介绍

@Digits 注解用于验证数值类型的字段是否符合指定的整数和小数位数。

18.2 注解属性介绍integer: 指定整数部分的最大位数。fraction: 指定小数部分的最大位数。message: 自定义验证失败时的错误消息。18.3 注解业务案例

public class FinancialTransaction {    @Digits(integer = 10, fraction = 2, message = "交易金额格式不正确")    private BigDecimal amount;    // 其他交易属性...}public class FinancialTransaction {    @Digits(integer = 10, fraction = 2, message = "交易金额格式不正确", groups = TransactionChecks.class, payload = ErrorPayloads.class)    private BigDecimal amount;    // 交易金额必须是最多10位整数和2位小数。}
@PastOrPresent19.1 注解作用介绍

@PastOrPresent 注解用于验证日期类型的字段是否表示现在或过去的日期。

19.2 注解属性介绍message: 自定义验证失败时的错误消息。19.3 注解业务案例

import java.time.LocalDate;public class InsurancePolicy {    @PastOrPresent(message = "保险生效日期必须为当前或过去的日期")    private LocalDate effectiveDate;    // 其他保险属性...}import java.time.LocalDate;public class InsurancePolicy {    @PastOrPresent(message = "保险生效日期必须为当前或过去的日期", groups = InsuranceChecks.class, payload = ErrorPayloads.class)    private LocalDate effectiveDate;    // 保险生效日期验证,适用于保险单管理。}
@FutureOrPresent20.1 注解作用介绍

@FutureOrPresent 注解用于验证日期类型的字段是否表示现在或未来的日期。

20.2 注解属性介绍message: 自定义验证失败时的错误消息。20.3 注解业务案例

public class Appointment {    @FutureOrPresent(message = "预约日期必须是当前或未来的日期")    private LocalDate appointmentDate;    // 其他预约属性...}public class Appointment {    @FutureOrPresent(message = "预约日期必须是当前或未来的日期", groups = AppointmentChecks.class, payload = ErrorPayloads.class)    private LocalDate appointmentDate;    // 预约日期验证,适用于预约系统。}
@Valid21.1 注解作用介

@Valid 注解用于递归地验证关联的对象或集合中的元素。

21.2 注解属性介绍groups: 指定应应用于验证的组。payload: 指定应应用于验证的额外数据。21.3 注解业务案例

public class Order {    @Valid    private User customer;    @Valid    private List<OrderItem> items;    // 其他订单属性...}public class Order {    @Valid(groups = {OrderChecks.class, ItemChecks.class}, payload = {ErrorPayloads.class})    private List<OrderItem> items;    // 递归验证订单项列表,适用于订单详细处理。}
@Validated22.1 注解作用介绍

@Validated 注解用于指定验证时使用的验证组。

22.2 注解属性介绍groups: 指定应应用于验证的组。22.3 注解业务案例

public class PaymentService {    @Validated(PaymentChecks.class)    public void processPayment(PaymentDetails details) {        // 使用特定的验证组来处理支付详情    }}public class PaymentService {    @Validated(PaymentChecks.class)    public void processPayment(@Validated(PaymentDetailsChecks.class) PaymentDetails details) {        // 使用特定的验证组来处理支付详情。    }}
@ConvertGroup23.1 注解作用介绍

@ConvertGroup 注解用于在验证过程中将一个分组转换为另一个分组。

23.2 注解属性介绍from: 指定原始分组。to: 指定目标分组。23.3 注解业务案例

public class DataMigrationService {    @ConvertGroup(from = LegacyDataChecks.class, to = CurrentDataChecks.class)    public void migrateData(LegacyData data) {        // 从旧数据验证转换为新数据验证    }}public class DataMigrationService {    @ConvertGroup(from = LegacyDataChecks.class, to = CurrentDataChecks.class)    public void migrateData(@Validated(LegacyDataChecks.class) LegacyData data) {        // 从旧数据验证转换为新数据验证。    }}
@ReportAsSingleViolation24.1 注解作用介绍

@ReportAsSingleViolation 注解用于将验证过程中的所有违反约束的情况报告为单个验证错误。

24.2 注解属性介绍message: 自定义验证失败时的错误消息。24.3 注解业务案例

public class CriticalField {    @ReportAsSingleViolation(message = "关键字段验证失败")    private String field;    // 其他属性...}public class CriticalField {    @ReportAsSingleViolation(message = "关键字段验证失败")    private String field;    // 将所有违反约束的情况报告为单个验证错误。}
@Groups25.1 注解作用介绍

@Groups 注解用于指定验证的分组,允许在不同场景下应用不同的验证规则。

25.2 注解属性介绍无特定属性,通常与 @Valid@Validated 注解一起使用。25.3 注解业务案例

public class User {    @Valid    private Profile profile;    // 其他用户属性...}public class Profile {    @NotNull(groups = RegistrationChecks.class)    private String biography;    // 其他个人资料属性...}
@SafeHtml26.1 注解作用介绍

@SafeHtml 注解用于验证HTML内容是否是安全的,防止跨站脚本(XSS)攻击。

26.2 注解属性介绍message: 自定义验证失败时的错误消息。26.3 注解业务案例

public class HtmlContent {    @SafeHtml(message = "内容包含不安全的HTML")    private String content;    // 其他HTML内容属性...}
@EAN27.1 注解作用介绍

@EAN 注解用于验证国际标准书号(ISBN)或欧洲商品编号(EAN-13)。

27.2 注解属性介绍message: 自定义验证失败时的错误消息。27.3 注解业务案例

public class Product {    @EAN(message = "无效的EAN或ISBN编号")    private String ean;    // 验证国际标准书号或欧洲商品编号}
@URL28.1 注解作用介绍

虽然 @URL注解在JSR 380规范中没有定义,但Hibernate Validator提供了类似的功能,用于验证字符串是否是有效的URL格式。

28.2 注解属性介绍message: 自定义验证失败时的错误消息。protocol: 指定必须的协议(如http, https)。host: 指定必须的主机名。port: 指定端口号。regexp: 自定义的URL匹配正则表达式。28.3 注解业务案例

public class Website {    @URL(message = "无效的URL")    private String url;    // 其他网站属性...}public class Website {    @URL(message = "无效的URL", protocol = "https", host = "example.com", port = 443)    private String url;    // 验证字符串是否是有效的URL格式
注解验证综合性案例场景描述

电商平台,用户可以浏览商品、下单购买,并进行订单管理。该平台需要验证用户信息、商品详情、订单数据以及支付信息的准确性和有效性。

业务实体和验证需求用户信息(User):必须包含有效的电子邮件和非空的用户名。商品详情(Product):需要有有效的库存数量和价格范围。订单(Order):必须包含用户信息、商品列表,并且总金额必须为正数。订单项(OrderItem):每个订单项需要验证购买数量和商品ID。支付信息(PaymentInfo):需要验证支付金额是否正确,并且支付方式是否被接受。

import javax.validation.constraints.*;import javax.validation.Valid;import java.util.List;public class ECommercePlatform {    // 用户信息    public class User {        @Email(message = "电子邮件地址无效", groups = UserChecks.class)        private String email;        @NotBlank(message = "用户名不能为空", groups = UserChecks.class)        private String username;        // 用户相关方法...    }    // 商品详情    public class Product {        @NotNull(message = "商品ID不能为空", groups = ProductChecks.class)        private String productId;        @PositiveOrZero(message = "库存数量不能为负数", groups = ProductChecks.class)        private int stock;        @DecimalMin(value = "0.01", message = "商品价格必须至少为0.01", groups = ProductChecks.class)        private BigDecimal price;        // 商品相关方法...    }    // 订单    public class Order {        @Valid        private User user;        @Valid        @Size(min = 1, message = "订单至少需要一个商品项", groups = OrderChecks.class)        private List<OrderItem> items;        @Positive(message = "订单总金额必须为正数", groups = OrderChecks.class)        private BigDecimal totalAmount;        // 订单相关方法...    }    // 订单项    public class OrderItem {        @NotNull(message = "商品ID不能为空", groups = ItemChecks.class)        private String productId;        @Positive(message = "购买数量必须为正数", groups = ItemChecks.class)        private int quantity;        // 订单项相关方法...    }    // 支付信息    public class PaymentInfo {        @Positive(message = "支付金额必须为正数", groups = PaymentChecks.class)        private BigDecimal amount;        @NotBlank(message = "支付方式不能为空", groups = PaymentChecks.class)        private String method;        // 支付信息相关方法...    }}//验证组定义public interface UserChecks {}public interface ProductChecks {}public interface OrderChecks {}public interface ItemChecks {}public interface PaymentChecks {}//错误元数据载荷public class ErrorPayloads implements Payload {}

在这个综合性业务场景中,我们使用了 @NotNull@NotBlank@PositiveOrZero@DecimalMin@Positive@Email等注解来确保数据的有效性。 @Valid注解用于递归验证嵌套对象,而自定义验证组(如 UserChecksProductChecks等)允许我们在不同的场景下应用不同的验证规则。 ErrorPayloads类用于携带额外的元数据,这些元数据可以在验证失败时由验证器使用。

在线预订系统分组验证场景描述

在线预订系统允许用户根据其类型(个人或公司)进行预订。系统需要对不同类型的预订应用不同的验证规则。

import javax.validation.*;import javax.validation.constraints.*;import java.time.LocalDate;import java.util.Set;// 验证组接口public interface PersonalBookingChecks {}public interface CorporateBookingChecks {}// 预订类型枚举public enum BookingType {    PERSONAL, CORPORATE;}// 预订实体类public class Booking {    private BookingType type;    // 个人预订字段    @NotBlank(message = "个人预订的姓名必须填写", groups = PersonalBookingChecks.class)    private String personalName;    @Email(message = "个人预订的电子邮箱格式必须正确", groups = PersonalBookingChecks.class)    private String personalEmail;    // 公司预订字段    @NotBlank(message = "公司预订的公司名称必须填写", groups = CorporateBookingChecks.class)    private String corporateName;    @PositiveOrZero(message = "公司预订的税务编号必须是非负数", groups = CorporateBookingChecks.class)    private Long corporateTaxId;    // 所有预订类型共有的字段    @NotNull(message = "入住日期不能为空")    private LocalDate checkInDate;    @NotNull(message = "退房日期不能为空")    private LocalDate checkOutDate;    // 用于设置预订类型的setter方法    public void setBookingType(BookingType type) {        this.type = type;    }}// 服务层验证逻辑public class BookingService {    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();    public void processBooking(Booking booking) {        Set<ConstraintViolation<Booking>> violations;        switch (booking.getType()) {            case PERSONAL:                violations = validator.validate(booking, PersonalBookingChecks.class);                break;            case CORPORATE:                violations = validator.validate(booking, CorporateBookingChecks.class);                break;            default:                throw new IllegalStateException("未知的预订类型");        }        if (!violations.isEmpty()) {            // 将验证错误转换为用户友好的字符串信息            throw new IllegalArgumentException("预订验证失败: " + formatValidationErrors(violations));        }        // 如果验证通过,继续处理预订逻辑,例如保存到数据库        // 省略处理预订的代码...    }    private String formatValidationErrors(Set<ConstraintViolation<Booking>> violations) {        StringBuilder sb = new StringBuilder();        for (ConstraintViolation<Booking> violation : violations) {            sb.append(violation.getPropertyPath()).append(": ").append(violation.getMessage()).append("\n");        }        return sb.toString();    }    // 省略其他服务方法...}// 测试类public class BookingApplication {    public static void main(String[] args) {        BookingService service = new BookingService();        Booking booking = new Booking();        // 这里设置了booking的属性和类型...        // 处理预订        service.processBooking(booking);    }}

上述代码, Booking类包含了根据不同预订类型(个人或公司)所需的不同字段,并使用相应的JSR 380注解进行了验证。 BookingService类中的 processBooking方法根据 Booking对象的类型使用分组验证,并处理验证结果。如果存在验证错误,它将抛出一个包含所有错误的 IllegalArgumentException异常。

标签: #java 数据校验 #java数据校验工具有哪些