卧槽,@Email 邮箱参数校验,巨坑!

1,047 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情


哈喽,大家好,我是一条。

相信大家都遇到过保存邮箱信息的需求,就是这么一个简单的需求,昨天我就在邮箱校验上踩了一个巨坑!

先看下我的做法,如果你能一眼看出问题,尊称你一声大佬!

Error Case

此处为模拟代码,非真实业务代码。

    @PostMapping("/5")
    public void test5(@Valid @RequestBody List<ValidListDTO> email){
        System.out.println("5");
    }
@Data
public class ValidListDTO {
    @NotBlank
    String name;

    @Email(message = "email不合法")
    String email;
}

这里说明一下,@Valid @RequestBody List<?>这个组合是可以校验集合的,需要在 controller 加上 @Validated

做个测试

  • 入参1:
[
  {
    "name": "name_r71gt",
    "email": "123@123"
  }
]
  • 入参2:
[
  {
    "name": "name_tmla4",
    "email": "email_f4qiw"
  }
]
  • 入参3:
[
  {
    "name": "name_tmla4",
    "email": "123@123.com"
  }
]

猜一猜

三个入参哪几个能正常执行呢?不墨迹,公布答案:

  • 入参 1 和入参 3:正常打印。

  • 入参 2 :

// 做了异常处理
{
  "code": "-1",
  "msg": " email不合法",
  "data": null
}

发现问题了吗?123@123竟然校验通过了!

即只要有@,并且@前后都有内容,就符合规则,那这肯定是个巨坑

Correct Case

正确的用法是要么继续使用@Email,显示的指定正则表达式,如下:

@Email(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\\\.[a-zA-Z0-9-]+)*\\\\.[a-zA-Z0-9]{2,6}$")
String email;

其实用注解的方式,对于异常信息的处理还有些不够灵活,如果对异常要求比较复杂严格,不如自己校验:

String emailMatcher="^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$";
Pattern.matches(emailMatcher,ent.getEmail());

总结

虽然在测试面前打脸了(一个邮箱校验改了好几次),但是发现个坑,也算是有所收获。

特此分享,与君共避。

再唠叨几句

有了解这块源码的大佬可以在评论区解释一下原因,看过源码发现regexp()的默认值是".*"


@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
public @interface Email {
	/**
	 * @return an additional regular expression the annotated element must match. The default
	 * is any string ('.*')
	 */
	String regexp() default ".*";
 }

@Constraint(validatedBy = { })应该是对应的校验函数,谁想到就一个大括号{},懵了!