如何在Java类中实现属性的输入校验与自动修正

来源:Vuejs社区作者:南京网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何在Java类中实现属性的输入校验与自动修正》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在Java类中实现属性的输入校验与自动修正》有用,将其分享出去将是对创作者最好的鼓励。

在Java开发中,类的属性输入校验与自动修正是保障数据合法性的重要环节,合理的实现方式可以减少业务层的重复校验代码,降低数据异常风险。

如何在Java类中实现属性的输入校验与自动修正

手动校验与修正实现

最基础的方式是在属性的setter方法中嵌入校验和修正逻辑,这种方式简单直接,适合属性较少、校验规则简单的场景。

下面以用户类为例,对年龄和用户名属性做校验和修正:

public class User {
    private String username;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        // 校验:用户名不能为空,为空时自动修正为默认游客名
        if (username == null || username.trim().isEmpty()) {
            this.username = "默认游客";
        } else {
            // 修正:去除用户名前后空格
            this.username = username.trim();
        }
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // 校验:年龄不能小于0,大于120,超出范围时自动修正为合法值
        if (age < 0) {
            this.age = 0;
        } else if (age > 120) {
            this.age = 120;
        } else {
            this.age = age;
        }
    }
}

结合Bean Validation实现校验

当校验规则较多时,手动编写setter逻辑会显得冗余,我们可以结合Bean Validation规范,使用注解标注校验规则,再通过校验工具触发校验。

首先需要在项目中引入Bean Validation的依赖,以Maven为例:

<dependency>
    <groupId>jakarta.validation</groupId>
    <artifactId>jakarta.validation-api</artifactId>
    <version>3.0.2</version>
</dependency>
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>8.0.0.Final</version>
</dependency>

然后在类的属性上添加校验注解,同时保留setter中的修正逻辑:

import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;

public class User {
    @NotBlank(message = "用户名不能为空")
    private String username;
    @Min(value = 0, message = "年龄不能小于0")
    @Max(value = 120, message = "年龄不能大于120")
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        // 修正逻辑:去除前后空格
        if (username != null) {
            this.username = username.trim();
        } else {
            this.username = null;
        }
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // 修正逻辑:超出范围自动修正
        if (age < 0) {
            this.age = 0;
        } else if (age > 120) {
            this.age = 120;
        } else {
            this.age = age;
        }
    }
}

校验时可以通过Validator实例触发:

import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        User user = new User();
        user.setUsername("  testUser  ");
        user.setAge(150);

        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<User>> violations = validator.validate(user);
        if (!violations.isEmpty()) {
            for (ConstraintViolation<User> violation : violations) {
                System.out.println(violation.getMessage());
            }
        }
        System.out.println("修正后用户名:" + user.getUsername());
        System.out.println("修正后年龄:" + user.getAge());
    }
}

自定义校验器实现复杂规则

如果遇到Bean Validation内置注解无法满足的复杂校验规则,我们可以自定义校验注解和校验器,同时结合修正逻辑。

例如我们需要校验手机号格式,并且自动去除手机号中的空格和横线:

首先定义自定义注解:

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPhone {
    String message() default "手机号格式不正确";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

然后实现对应的校验器:

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;

public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\d{9}$");

    @Override
    public void initialize(ValidPhone constraintAnnotation) {
    }

    @Override
    public boolean isValid(String phone, ConstraintValidatorContext context) {
        if (phone == null) {
            return false;
        }
        // 先去除空格和横线再校验
        String cleanedPhone = phone.replaceAll("[\s-]", "");
        return PHONE_PATTERN.matcher(cleanedPhone).matches();
    }
}

在类中使用该注解并添加修正逻辑:

import jakarta.validation.constraints.NotBlank;

public class User {
    @NotBlank(message = "手机号不能为空")
    @ValidPhone
    private String phone;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        // 自动修正:去除手机号中的空格和横线
        if (phone != null) {
            this.phone = phone.replaceAll("[\s-]", "");
        } else {
            this.phone = null;
        }
    }
}

不同实现方式对比

我们可以通过下表对比几种实现方式的特点,选择适合自己场景的方案:

实现方式优点缺点适用场景
手动校验修正无额外依赖,逻辑直观重复代码多,规则复杂时维护成本高属性少、规则简单的类
Bean Validation注解规则声明清晰,减少重复代码需要引入额外依赖,复杂规则需要扩展规则较多、符合标准校验场景的类
自定义校验器支持复杂自定义规则,扩展性强需要额外编写注解和校验器代码有特殊校验需求的场景

注意事项

  • 修正逻辑不要改变数据的原始语义,比如年龄修正为0是合理的边界处理,但不要将负数年龄修正为随机正数
  • 如果类会被序列化或反序列化,要确保setter中的校验修正逻辑会被正确触发
  • 校验和修正的异常信息要做好记录,方便后续排查数据问题

Java属性校验自动修正Bean_Validation修改时间:2026-07-21 17:30:40

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。