持续创作,加速成长!这是我参与「掘金日新计划 · 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 = { })
应该是对应的校验函数,谁想到就一个大括号{}
,懵了!