0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SpringBoot参数验证的10个技巧1

jf_78858299 来源:JAVA旭阳 作者:JAVA旭阳 2023-04-07 15:10 次阅读

前言

参数验证很重要,是平时开发环节中不可少的一部分,但是我想很多后端同事会偷懒,干脆不错,这样很可能给系统的稳定性和安全性带来严重的危害。那么在Spring Boot应用中如何做好参数校验工作呢,本文提供了10个小技巧,你知道几个呢?

1.使用验证注解

Spring Boot提供了内置的验证注解,可以帮助简单、快速地对输入字段进行验证,例如检查 null 或空字段、强制执行长度限制、使用正则表达式验证模式以及验证电子邮件地址。

一些最常用的验证注释包括:

  • @NotNull:指定字段不能为空。
  • @NotEmpty:指定列表字段不能为空。
  • @NotBlank:指定字符串字段不得为空或仅包含空格。
  • @Min@Max:指定数字字段的最小值和最大值。
  • @Pattern:指定字符串字段必须匹配的正则表达式模式。
  • @Email:指定字符串字段必须是有效的电子邮件地址。

具体用法参考下面例子:

public class User {
    @NotNull
    private Long id;

    @NotBlank
    @Size(min = 2, max = 50)
    private String firstName;

    @NotBlank
    @Size(min = 2, max = 50)
    private String lastName;

    @Email
    private String email;

    @NotNull
    @Min(18)
    @Max(99)
    private Integer age;

    @NotEmpty
    private List

2 使用自定义验证注解

虽然 Spring Boot 的内置验证注释很有用,但它们可能无法涵盖所有情况。如果有特殊参数验证的场景,可以使用 Spring 的 JSR 303 验证框架创建自定义验证注释。自定义注解可以让你的的验证逻辑更具可重用性和可维护性。

假设我们有一个应用程序,用户可以在其中创建帖子。每个帖子都应该有一个标题和一个正文,并且标题在所有帖子中应该是唯一的。虽然 Spring Boot 提供了用于检查字段是否为空的内置验证注释,但它没有提供用于检查唯一性的内置验证注释。在这种情况下,我们可以创建一个自定义验证注解来处理这种情况。

首先,我们创建自定义约束注解UniqueTitle

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueTitleValidator.class)
public @interface UniqueTitle {
    String message() default "Title must be unique";

    Class?[] groups() default {};

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

接下来,我们创建一个PostRepository接口,目的是从数据库中检索帖子:

public interface PostRepository extends JpaRepository<Post, Long> {
    Post findByTitle(String title);
}

然后我们需要定义验证器类 UniqueTitleValidator,如下所示:

@Component
public class UniqueTitleValidator implements ConstraintValidator<UniqueTitle, String> {

    @Autowired
    private PostRepository postRepository;

    @Override
    public boolean isValid(String title, ConstraintValidatorContext context) {
        if (title == null) {
            return true;
        }
        return Objects.isNull(postRepository.findByTitle(title));
    }
}

UniqueTitleValidator实现了ConstraintValidator接口,它有两个泛型类型:第一个是自定义注解UniqueTitle,第二个是正在验证的字段类型(在本例中为String). 我们还自动装配了PostRepository 类以从数据库中检索帖子。

isValid()方法通过查询 PostRepository 来检查 title 是否为 null 或者它是否是唯一的。如果 title 为 null 或唯一,则验证成功,并返回 true。

定义了自定义验证注释和验证器类后,我们现在可以使用它来验证 Spring Boot 应用程序中的帖子标题:

public class Post {
    @UniqueTitle
    private String title;

    @NotNull
    private String body;
}

我们已将 @UniqueTitle 注释应用于 Post 类中的 title 变量。验证此字段时,这将触发 UniqueTitleValidator 类中定义的验证逻辑。

3 在服务器端验证

除了前端或者客户端做了验证意外,服务器端验证输入是至关重要的。它可以确保在处理或存储任何恶意或格式错误的数据之前将其捕获,这对于应用程序的安全性和稳定性至关重要。

假设我们有一个允许用户创建新帐户的 REST 端点。端点需要一个包含用户用户名和密码的 JSON 请求体。为确保输入有效,我们可以创建一个 DTO(数据传输对象)类并将验证注释应用于其字段:

public class UserDTO {

    @NotBlank
    private String username;

    @NotBlank
    private String password;
}

我们使用@NotBlank注解来确保usernamepassword字段不为空或 null。

接下来,我们可以创建一个控制器方法来处理 HTTP POST 请求并在创建新用户之前验证输入:

@RestController
@RequestMapping("/users")
@Validated
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity

我们使用 Spring 的@Validated注解来启用方法级验证,我们还将 @Valid 注释应用于 userDto 参数以触发验证过程。

4 提供有意义的错误信息

当验证失败时,必须提供清晰简洁的错误消息来描述出了什么问题以及如何修复它。

这是一个示例,如果我们有一个允许用户创建新用户的 RESTful API。我们要确保姓名和电子邮件地址字段不为空,年龄在 18 到 99 岁之间,除了这些字段,如果用户尝试使用重复的“用户名”创建帐户,我们还会提供明确的错误消息或“电子邮件”。

为此,我们可以定义一个带有必要验证注释的模型类 User,如下所示:

public class User {

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

    @NotBlank(message = "Email不能为空")
    @Email(message = "无效的Emaild地址")
    private String email;

    @NotNull(message = "年龄不能为空")
    @Min(value = 18, message = "年龄必须大于18")
    @Max(value = 99, message = "年龄必须小于99")
    private Integer age;
}
  • 我们使用 message属性为每个验证注释提供了自定义错误消息。

接下来,在我们的 Spring 控制器中,我们可以处理表单提交并使用 @Valid 注释验证用户输入:

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody User user, BindingResult result) {
        if (result.hasErrors()) {
            List<String> errorMessages = result.getAllErrors().stream()
                    .map(DefaultMessageSourceResolvable::getDefaultMessage)
                    .collect(Collectors.toList());
            return ResponseEntity.badRequest().body(errorMessages.toString());
        }

        // save the user to the database using UserService
        userService.saveUser(user);

        return ResponseEntity.status(HttpStatus.CREATED).body("User created successfully");
    }
}
  • 我们使用 @Valid 注释来触发 User 对象的验证,并使用 BindingResult 对象来捕获任何验证错误。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 开发
    +关注

    关注

    0

    文章

    366

    浏览量

    40806
  • 参数
    +关注

    关注

    11

    文章

    1779

    浏览量

    32079
  • spring
    +关注

    关注

    0

    文章

    338

    浏览量

    14307
  • SpringBoot
    +关注

    关注

    0

    文章

    173

    浏览量

    167
收藏 人收藏

    评论

    相关推荐

    SpringBoot配置Mybatis的2错误和修正

    SpringBoot】配置Mybatis错误
    发表于 04-19 10:31

    SpringBoot中的Druid介绍

    SpringBoot中Druid数据源配置
    发表于 05-07 09:21

    SpringBoot知识总结

    SpringBoot干货学习总结
    发表于 08-01 10:40

    怎么学习SpringBoot

    SpringBoot学习之路(X5)- 整合JPA
    发表于 06-10 14:52

    springboot集成mqtt

    springboot集成mqtt,大纲一.数据入库1.数据入库解决方案二.开发实时订阅发布展示页面1.及时通讯技术2.技术整合
    发表于 07-16 07:53

    怎样去使用springboot

    怎样去使用springboot呢?学习springboot需要懂得哪些?
    发表于 10-25 07:13

    SpringBoot应用启动运行run方法

    什么时候创建嵌入式的Servlet容器工厂?什么时候获取嵌入式的Servlet容器并启动Tomcat;获取嵌入式的Servlet容器工厂:1)、SpringBoot应用启动运行run方法2
    发表于 12-20 06:16

    怎样去设计一基于springboot+freemark+jpa+MySQL的在线电影订票系统

    实现的功能有:前台: 1、正在上映的电影浏览查看,可在线播放预告视频。 2、影院信息浏览查看,包括各影院上映场次数。 3、新闻咨询信息浏览查看。 4、地域信息查看切换。 5、用户注册登录,登录支持发送短信验证码登录和...
    发表于 01-03 07:22

    无需注解的SpringBoot API文档生成神器

    如果提交的表单是 application/x-www-form-urlencoded 类型的key/value格式,你可以在 SpringBoot 端通过在 @param 参数后添加字段解释或者在相关的JavaBean对象里面添加解释:
    的头像 发表于 03-13 09:38 899次阅读

    什么是 SpringBoot

    本文从为什么要有 `SpringBoot`,以及 `SpringBoot` 到底方便在哪里开始入手,逐步分析了 `SpringBoot` 自动装配的原理,最后手写了一简单的 `sta
    的头像 发表于 04-07 11:28 1262次阅读
    什么是 <b class='flag-5'>SpringBoot</b>?

    SpringBoot常用注解及使用方法1

    基于 SpringBoot 平台开发的项目数不胜数,与常规的基于`Spring`开发的项目最大的不同之处,SpringBoot 里面提供了大量的注解用于快速开发,而且非常简单,基本可以做到开箱即用! 那 SpringBoot
    的头像 发表于 04-07 11:51 675次阅读

    SpringBoot的核心注解1

    今天跟大家来探讨下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot为什么不需要XML,达到零配置
    的头像 发表于 04-07 14:34 669次阅读
    <b class='flag-5'>SpringBoot</b>的核心注解<b class='flag-5'>1</b>

    SpringBoot的核心注解2

    今天跟大家来探讨下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot为什么不需要XML,达到零配置
    的头像 发表于 04-07 14:34 1925次阅读
    <b class='flag-5'>SpringBoot</b>的核心注解2

    SpringBoot参数验证10技巧2

    如果你的应用程序支持多种语言,则必须使用国际化 (i18n) 以用户首选语言显示错误消息。 以下是在 Spring Boot 应用程序中使用 i18n 处理错误消息的示例
    的头像 发表于 04-07 15:11 1375次阅读

    注解搞定SpringBoot接口防刷

    技术要点:springboot的基本知识,redis基本操作,
    的头像 发表于 11-28 10:46 386次阅读