受到效能後端競賽編碼的啟發,本文進行了一項測試,以找到 Java 應用程式最快的驗證器。
一個非常簡單的場景:只需驗證使用者的電子郵件。
1、Hibernate Validator
public record User( @NotNull @Email String email ){}
@RestController @Validated public class HibernateValidatorController {
@Autowired private Validator validator;
@GetMapping(<font>"/validate-hibernate") public ResponseEntity<String> validateEmail(@RequestParam String email) {
|
HibernateValidatorController 類使用 jakarta.validation.Validator(這只是 Hibernate Validator 實現的介面)
2、正規表示式
static final String EMAIL_REGEX = <font>"^[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(<font>"@"); 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.