it编程 > 软件设计 > 设计模式

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

113人参与 2024-08-06 设计模式

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

历史热点文章

@notnull

1.1 注解作用介绍

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

1.2 注解属性介绍

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属性可用于携带额外的元数据,供验证器使用。
}

@notblank

2.1 注解作用介绍

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

2.2 注解属性介绍

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组。
}

@notempty

3.1 注解作用介绍

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

3.2 注解属性介绍

3.3 注解业务案例

public class message {
    @notempty(message = "消息内容不能为空")
    private string text;

    // 其他消息属性...
}

public class message {
    @notempty(message = "消息内容不能为空", groups = messagechecks.class, payload = errorpayloads.class)
    private string text;

    // 消息文本不能为空,适用于消息发送场景。
}

@size

4.1 注解作用介绍

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

4.2 注解属性介绍

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;

    // 书名长度限制,适用于图书管理系统。
}

@past

5.1 注解作用介绍

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

5.2 注解属性介绍

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;

    // 事件日期应为过去日期,适用于历史事件记录。
}

@future

6.1 注解作用介绍

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

6.2 注解属性介绍

6.3 注解业务案例

public class delivery {
    @future(message = "预计送达日期必须是未来的日期")
    private localdate expecteddeliverydate;

    // 其他送达属性...
}

public class delivery {
    @future(message = "预计送达日期必须是未来的日期", groups = deliverychecks.class, payload = errorpayloads.class)
    private localdate expecteddeliverydate;

    // 预计送达日期应为未来日期,适用于订单处理系统。
}

@pattern

7.1 注解作用介绍

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

7.2 注解属性介绍

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;

    // 电子邮箱格式验证,适用于用户注册表单。
}

@min

8.1 注解作用介绍

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

8.2 注解属性介绍

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;

    // 购买数量验证,适用于购物车系统。
}

@max

9.1 注解作用介绍

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

9.2 注解属性介绍

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;

    // 库存数量验证,适用于库存管理系统。
}

@decimalmin

10.1 注解作用介绍

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

10.2 注解属性介绍

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;

    // 价格必须为非负值,适用于财务管理系统。
}

@decimalmax

11.1 注解作用介绍

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

11.2 注解属性介绍

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;

    // 价格上限验证,适用于定价策略。
}

@email

12.1 注解作用介绍

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

12.2 注解属性介绍

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;

    // 电子邮箱地址验证,适用于用户信息管理。
}

@valid

13.1 注解作用介绍

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

13.2 注解属性介绍

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 注解属性介绍

14.3 注解业务案例

public class account {
    @positive(message = "账户余额必须为正数")
    private bigdecimal balance;

    // 其他账户属性...
}

public class account {
    @positive(message = "账户余额必须为正数", groups = accountchecks.class, payload = errorpayloads.class)
    private bigdecimal balance;

    // 账户余额验证,适用于银行账户管理。
}

@positiveorzero

15.1 注解作用介绍

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

15.2 注解属性介绍

15.3 注解业务案例

public class account {
    @positiveorzero(message = "账户余额不能为负数")
    private bigdecimal balance;

    // 其他账户属性...
}

public class account {
    @positiveorzero(message = "账户余额不能为负数", groups = accountchecks.class, payload = errorpayloads.class)
    private bigdecimal balance;

    // 账户余额验证,确保余额非负。
}

@negative

16.1 注解作用介绍

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

16.2 注解属性介绍

16.3 注解业务案例

public class debt {
    @negative(message = "债务金额必须为负数")
    private bigdecimal amount;

    // 其他债务属性...
}

public class debt {
    @negative(message = "债务金额必须为负数", groups = debtchecks.class, payload = errorpayloads.class)
    private bigdecimal amount;

    // 债务金额验证,适用于债务管理。
}

@negativeorzero

17.1 注解作用介绍

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

17.2 注解属性介绍

17.3 注解业务案例

public class debt {
    @negativeorzero(message = "债务金额不能为正数")
    private bigdecimal amount;

    // 其他债务属性...
}
public class debt {
    @negativeorzero(message = "债务金额不能为正数", groups = debtchecks.class, payload = errorpayloads.class)
    private bigdecimal amount;

    // 债务金额验证,确保债务非正。
}

@digits

18.1 注解作用介绍

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

18.2 注解属性介绍

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位小数。
}

@pastorpresent

19.1 注解作用介绍

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

19.2 注解属性介绍

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;

    // 保险生效日期验证,适用于保险单管理。
}

@futureorpresent

20.1 注解作用介绍

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

20.2 注解属性介绍

20.3 注解业务案例

public class appointment {
    @futureorpresent(message = "预约日期必须是当前或未来的日期")
    private localdate appointmentdate;

    // 其他预约属性...
}
public class appointment {
    @futureorpresent(message = "预约日期必须是当前或未来的日期", groups = appointmentchecks.class, payload = errorpayloads.class)
    private localdate appointmentdate;

    // 预约日期验证,适用于预约系统。
}

@valid

21.1 注解作用介

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

21.2 注解属性介绍

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;

    // 递归验证订单项列表,适用于订单详细处理。
}

@validated

22.1 注解作用介绍

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

22.2 注解属性介绍

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) {
        // 使用特定的验证组来处理支付详情。
    }
}

@convertgroup

23.1 注解作用介绍

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

23.2 注解属性介绍

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) {
        // 从旧数据验证转换为新数据验证。
    }
}

@reportassingleviolation

24.1 注解作用介绍

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

24.2 注解属性介绍

24.3 注解业务案例

public class criticalfield {
    @reportassingleviolation(message = "关键字段验证失败")
    private string field;

    // 其他属性...
}
public class criticalfield {
    @reportassingleviolation(message = "关键字段验证失败")
    private string field;

    // 将所有违反约束的情况报告为单个验证错误。
}

@groups

25.1 注解作用介绍

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

25.2 注解属性介绍

25.3 注解业务案例

public class user {
    @valid
    private profile profile;

    // 其他用户属性...
}
public class profile {
    @notnull(groups = registrationchecks.class)
    private string biography;

    // 其他个人资料属性...
}

@safehtml

26.1 注解作用介绍

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

26.2 注解属性介绍

26.3 注解业务案例

public class htmlcontent {
    @safehtml(message = "内容包含不安全的html")
    private string content;

    // 其他html内容属性...
}

@ean

27.1 注解作用介绍

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

27.2 注解属性介绍

27.3 注解业务案例

public class product {
    @ean(message = "无效的ean或isbn编号")
    private string ean;

    // 验证国际标准书号或欧洲商品编号
}

@url

28.1 注解作用介绍

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

28.2 注解属性介绍

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格式

注解验证综合性案例

场景描述

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

业务实体和验证需求

  1. 用户信息(user):必须包含有效的电子邮件和非空的用户名。
  2. 商品详情(product):需要有有效的库存数量和价格范围。
  3. 订单(order):必须包含用户信息、商品列表,并且总金额必须为正数。
  4. 订单项(orderitem):每个订单项需要验证购买数量和商品id。
  5. 支付信息(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异常。

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

免费领取云主机,在华为开发者空间玩转YOLOV3

08-06

Spring Boot 基于 SCRAM 认证集成 Kafka 的详解

08-06

DDei在线设计器-加载数据

08-06

面向物联网的 NGINX Plus:对 MQTT 流量进行加密和身份验证

08-06

美团大规模KV存储挑战与架构实践

08-06

极客的盛会!GOTC 2024 带你直击硬核 AI 技术创新与实践

08-06

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论