清除空格党,光@NotBlank注解就能一招秒杀!🤯

560 阅读10分钟

🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升持续更新中,up!up!up!!

📜 前言

  哈咯,家人们,我又来摸鱼了!趁着领导去开会的时间,跟大家简单聊点。我那同事昨早上不是刚找我给她补课:如何正确使用@TableField注解,这不,下午这会儿又给我下套整了个“难题”,@NotBlank注解咋用?我这同事咋这么会整活,这可太难了;我只能耐着性子跟她好好唠唠,毕竟招她进来我也参与了一部分决策。

  想必大家日常开发中也会经常遇到表单验证的问题,使用过它的同学一定会觉得——没有 @NotBlank 就像早晨忘了洗脸,总觉得不太清爽!有木有??说实在的,😆 数据校验是我们开发中不可或缺的一部分,特别是页面新增/修改等页面表单输入,空白符可谓是“数据污染”的罪魁祸首。没填内容的空格、不走心的空字符串——这些都是我们不想要的!那可有一招制敌之法?

  我的回答是,必须有!@NotBlank 注解就可以实现;它是 Java Bean Validation 提供的一个小注解,可以确保字符串输入不只是“空壳子”,从而提高了表单内容输入的有效性。今天我们就一起来玩玩 @NotBlank ,看看它是如何默默无闻地帮助我们管理那些“不走心”的输入吧!👀会的同学可以粗略过一遍,不会的同学特别是我那同事!认真看好好学,别走神,因为我只教这一遍。

📚 目录

  1. 🧐 什么是 @NotBlank?它究竟能帮你做什么?
  2. 🎩 @NotBlank 的基本用法:直接上手!
  3. ✍️ 实战演示:在 Spring Boot 项目中使用 @NotBlank
  4. 🔄 @NotBlank 与其他校验注解的区别(@NotNull、@NotEmpty)
  5. 🛠️ 高阶组合:与其他注解“配合默契”
  6. 🤓 @NotBlank 是如何工作的?
  7. 💡 最佳实践与常见坑:不要掉坑里哟!
  8. 📈 总结与心得:用得好,它能让你“如虎添翼”!

🧐 什么是 @NotBlank?它究竟能帮你做什么?

  首先,@NotBlank 来自 Jakarta Bean Validation(以前称为 Javax Bean Validation)规范,其具体实现通常是 Hibernate Validator(这是 Bean Validation 的参考实现)。完整路径:javax.validation.constraints.NotBlank

  @NotBlank 是一个非常实用的小注解,专门用于检查字符串是否为 “非空白”。注意,是“非空白”哦!它不仅仅是要求字段不为空(null),还要求内容不能全是空格。🎯

  你是否也遇到过这样的情况:用户在输入框里敲了几个空格,然后直接点击提交了?@NotBlank 就是来解决这种尴尬的情形的!它是 Java Bean Validation API 中提供的注解,位于 javax.validation.constraints 包下,用于确保字符串字段有效填充,防止用户“划水”输入。

🎩 @NotBlank 的基本用法:直接上手!

  @NotBlank 的使用非常简单,只需要将它添加在字符串字段前即可,通常用于 Web 表单或 API 请求的参数校验。举个例子,我们有一个用户注册的接口,用户需要输入用户名和密码。使用 @NotBlank 后,Spring 就会自动验证这些字段,防止用户输入空白内容。

示例代码如下:

import javax.validation.constraints.NotBlank;

public class UserRegistration {

    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;

    // Getter 和 Setter
}

  这里的 @NotBlank 会确保 usernamepassword 字段都被用户有效填写,不是 null 或空白字符。如果验证不通过,message 的内容会作为错误提示返回给用户。

✍️ 实战演示:在项目中使用 @NotBlank注解

  接下来,我们来模拟一个小场景,看看 @NotBlank 在项目中是如何使用的,包含从表单输入到返回验证信息的完整流程。

Step 1: 导入对应依赖

  首先,为了使用 @NotBlank,你需要在项目中引入一个支持 Jakarta Bean Validation 的实现库,比如 Hibernate Validator。

以下是常见的 Maven 依赖配置:

Maven 配置:

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>最新版本号</version>
</dependency>
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId> <!-- EL 表达式依赖 -->
    <version>最新版本号</version>
</dependency>

Gradle 配置:

implementation 'org.hibernate.validator:hibernate-validator:最新版本号'
implementation 'org.glassfish:javax.el:最新版本号'

Step 2: 创建验证实体类

  接着,我们定义一个用户信息实体,要求用户输入用户名和邮箱号,同时确保这些字段不能为空白:

/**
 * @author bug菌
 * @date 2024-12-02
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("user对象")
@TableName(value = "user")
public class User extends BaseEntity {
    private static final long serialVersionUID = 1L;

    @TableId
    private Long id;

    @ApiModelProperty(value = "逻辑删除标记(0-正常, 2-已删除)")
    @Excel(name = "逻辑删除标记", readConverterExp = "0=-正常,2=-已删除")
    @TableLogic
    private String delFlag = "0";

    @NotBlank(message = "姓名不能为空")
    private String name;

    @NotBlank(message = "邮箱号不能为空")
    private String email;
}

Step 3: 在 Controller 中使用 @Valid 触发验证

  在控制器层,我们可以使用 @Validated 注解来触发验证过程。如果 nameemail 字段为空白,系统会自动返回错误信息:

    @ApiOperation("新增user")
    @PostMapping("/add")
    public R<Void> add(@Validated @RequestBody User user) {
        return toR(userService.insert(user));
    }

Step 4: 处理验证失败的情况

  为了让验证信息更友好,可以通过全局异常处理器捕获验证失败的异常并自定义返回内容:

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public String handleValidationExceptions(MethodArgumentNotValidException ex) {
        return ex.getBindingResult().getFieldError().getDefaultMessage();
    }
}

  这样一来,当验证失败时,系统会返回我们设置的错误提示,告诉用户哪个字段未填写。

Step 5: 实际演示

  为了验证如上代码注解是否真正能够拦截这些情景,我们直接上Postman来模拟调用接口测试一下。

模拟场景1:用户名直接传空字符串""

  这里我们请求的时候,将name直接传个空串""进行请求。Postman请求如下:

=

  如上成功验证传入空串会被拦截。

模拟场景2:用户名输入全空格

  继续模拟,这里我们在发请求的时候,将name直接传个几个空格。Postman请求如下:

  如上成功验证传入空格依然会被拦截。

  总之,这里已经替大家都测试过了,大家可放心食用。

🔄 @NotBlank 与其他校验注解的区别(@NotNull、@NotEmpty)

  在 Spring 的验证注解圈中,还有几个常常被混淆的注解,比如 @NotNull@NotEmpty。这几个注解的功能看似相似,但其实在应用场景上还是有区别的,我简单给大家区分一下:

  1. @NotNull:只检查字段是否为 null,但允许空字符串。
  2. @NotEmpty:不仅检查 null,还不允许空字符串("")或空集合。
  3. @NotBlank:在 @NotEmpty 基础上更严格,要求字符串不能全是空白字符,适合用户输入验证。

示例代码如下:

public class Example {

    @NotNull(message = "此字段不能为空")
    private String notNullField;

    @NotEmpty(message = "此字段不能为空字符串")
    private String notEmptyField;

    @NotBlank(message = "此字段不能为全空白字符")
    private String notBlankField;
}

  在这个例子中,@NotBlank 的校验最严格,适合对用户输入的字段进行约束,以防用户用空格来“蒙混过关”,是不是非常的好使,大家可尽情测试体验它的强大校验之处。

🛠️ 高阶组合:与其他注解“配合默契”

  @NotBlank 在实际项目中可以与其他注解配合使用,确保数据更严格的校验。例如要求用户名不仅不为空白,还要符合特定长度限制。所以,我们可以这样组合用:

示例代码如下:

import javax.validation.constraints.Size;

public class UserRequest {

    @NotBlank(message = "用户名不能为空")
    @Size(min = 5, max = 20, message = "用户名长度必须在5到20个字符之间")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;
}

  在如上示例中,@NotBlank 可确保 username 字段不能为全空白或空字符串,@Size 能限制它的长度在 5 到 20 个字符之间。通过这种组合注解,我们可以实现更精细的输入校验及控制。

🤓 @NotBlank 是如何工作的?

  Spring 的 @NotBlank 注解其实是基于 Bean Validation 的 JSR 380 规范。Spring 在处理请求数据时,会检查字段上添加的校验注解,比如 @NotBlank,并调用其验证逻辑。@NotBlank 会先检查字段是否为 null,再判断字段内容是否为空白字符。如果字段不满足要求,就会触发验证错误,并返回指定的 message

  虽然看@NotBlank的源码中 validatedBy = {} 是空的,但 Hibernate Validator 本身就提供了默认的实现逻辑:

  • 检查字段是否为 null。
  • 检查字段是否为空字符串("")。
  • 检查字段是否仅包含空白字符(如 " ")。

  通过框架的 SPI(Service Provider Interface)机制,@NotBlank 的验证逻辑由默认实现类 org.hibernate.validator.internal.constraintvalidators.bv.NotBlankValidator 提供,用户无需手动实现验证器。对原理感兴趣的同学可以继续深究下去,这里我就简单介绍这么多。

💡 最佳实践与常见坑:不要掉坑里哟!

  1. 正确选择注解:根据字段类型选择合适的注解,如果是字符串,优先选择 @NotBlank。如果是其他类型(如列表、数组),可以选择 @NotEmpty@NotNull

  2. 自定义错误信息:为每个注解的 message 属性提供清晰的错误提示,这样用户在表单验证失败时可以得到直观的反馈。

  3. 注意多重校验顺序:当多个注解组合使用时,验证顺序可能会影响返回的错误信息。一般情况下 @NotBlank 应该放在最前面,确保基本的非空白验证优先执行。

  4. 结合全局异常处理:通过全局异常处理器集中管理验证错误信息,方便后期维护和管理。

📈 总结与心得

  @NotBlank 注解,虽然它是个很不起眼的注解,但是功能是无敌的,能够帮助我们在字符串输入中有效地防止无效输入,减少了很多if else的校验逻辑判断。尤其是在处理用户输入时,@NotBlank 能避免空白字符串带来的“假数据”问题,从而保障数据入库的准确性;同时,它的功能远不止这点,它还可以适配分组校验、重复校验等,这里我就不一一给大家详细解读了,我写此文抛砖引玉,希望有更多的同学能够主动进行探索并技术分享,带动更多的开发者热衷技术分享技术。

  最后,希望这篇文章能够让你(还有我的同事)对 @NotBlank 注解有更深入的理解!没用上的赶紧在你的项目中试试吧🎉,一天一个助你解放双手小技巧。

📣 关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿哇。

-End-