受到性能后端竞赛编码的启发,本文进行了一项测试,以找到 Java 应用程序最快的验证器。
一个非常简单的场景:只需验证用户的电子邮件。
1、Hibernate Validator
public record User( @NotNull @Email String email ){}
@RestController @Validated public class HibernateValidatorController {
@Autowired private Validator validator;
@GetMapping("/validate-hibernate") public ResponseEntity<String> validateEmail(@RequestParam String email) {
|
HibernateValidatorController 类使用 jakarta.validation.Validator(这只是 Hibernate Validator 实现的接口)
2、正则表达式
static final String EMAIL_REGEX = "^[A-Za-z0-9+_.-]+@(.+)$";
boolean isValid(String email) { return email != null && email.matches(EMAIL_REGEX); }
@GetMapping("/validate-regex") public ResponseEntity<String> validateEmail(@RequestParam String email) {
if (isValid(email)) { return ResponseEntity.ok("Valid email: 200 OK"); } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid email: 400 Bad Request"); }
}
|
regexController 类只是从请求中获取电子邮件,并使用 isValid 方法对其进行验证。
3、手工验证
boolean isValid(String email) { if (email == null) return false; int atIndex = email.indexOf("@"); int dotIndex = email.lastIndexOf(".");
return atIndex > 0 && dotIndex > atIndex + 1 && dotIndex < email.length() - 1; }
@GetMapping("/validate-programmatic") public ResponseEntity<String> validateEmail(@RequestParam String email) {
if (isValid(email)) { return ResponseEntity.ok("Valid email: 200 OK"); } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid email: 400 Bad Request"); }
}
|
programmaticController 类只是从请求中获取电子邮件,并使用 isValid 方法对其进行验证。
测试
我们使用 Apache JMeter 测试所有 3 个应用程序接口。
我们的模拟测试在 1000 个并发用户中循环运行 100 次,每次请求都会发送一封有效的电子邮件。
| API | avg | 99% | max | TPS | |--------------------------------|-----|-----|------|--------| | Regex API Thread Group | 18 | 86 | 254 | 17784 | | Programmatic API Thread Group | 13 | 67 | 169 | 19197 | | Hibernate API Thread Group | 10 | 59 | 246 | 19960 |
|
Hibernate Validator 是测试的最佳选择。
my GitHub.