前言
參數(shù)驗(yàn)證很重要,是平時(shí)開(kāi)發(fā)環(huán)節(jié)中不可少的一部分,但是我想很多后端同事會(huì)偷懶,干脆不錯(cuò),這樣很可能給系統(tǒng)的穩(wěn)定性和安全性帶來(lái)嚴(yán)重的危害。那么在Spring Boot應(yīng)用中如何做好參數(shù)校驗(yàn)工作呢,本文提供了10個(gè)小技巧,你知道幾個(gè)呢?
1.使用驗(yàn)證注解
Spring Boot
提供了內(nèi)置的驗(yàn)證注解,可以幫助簡(jiǎn)單、快速地對(duì)輸入字段進(jìn)行驗(yàn)證,例如檢查 null 或空字段、強(qiáng)制執(zhí)行長(zhǎng)度限制、使用正則表達(dá)式驗(yàn)證模式以及驗(yàn)證電子郵件地址。
一些最常用的驗(yàn)證注釋包括:
@NotNull
:指定字段不能為空。@NotEmpty
:指定列表字段不能為空。@NotBlank
:指定字符串字段不得為空或僅包含空格。@Min
和@Max
:指定數(shù)字字段的最小值和最大值。@Pattern
:指定字符串字段必須匹配的正則表達(dá)式模式。@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 使用自定義驗(yàn)證注解
雖然 Spring Boot 的內(nèi)置驗(yàn)證注釋很有用,但它們可能無(wú)法涵蓋所有情況。如果有特殊參數(shù)驗(yàn)證的場(chǎng)景,可以使用 Spring 的 JSR 303 驗(yàn)證框架創(chuàng)建自定義驗(yàn)證注釋。自定義注解可以讓你的的驗(yàn)證邏輯更具可重用性和可維護(hù)性。
假設(shè)我們有一個(gè)應(yīng)用程序,用戶可以在其中創(chuàng)建帖子。每個(gè)帖子都應(yīng)該有一個(gè)標(biāo)題和一個(gè)正文,并且標(biāo)題在所有帖子中應(yīng)該是唯一的。雖然 Spring Boot 提供了用于檢查字段是否為空的內(nèi)置驗(yàn)證注釋,但它沒(méi)有提供用于檢查唯一性的內(nèi)置驗(yàn)證注釋。在這種情況下,我們可以創(chuàng)建一個(gè)自定義驗(yàn)證注解來(lái)處理這種情況。
首先,我們創(chuàng)建自定義約束注解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 {};
}
接下來(lái),我們創(chuàng)建一個(gè)PostRepository
接口,目的是從數(shù)據(jù)庫(kù)中檢索帖子:
public interface PostRepository extends JpaRepository<Post, Long> {
Post findByTitle(String title);
}
然后我們需要定義驗(yàn)證器類 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
實(shí)現(xiàn)了ConstraintValidator
接口,它有兩個(gè)泛型類型:第一個(gè)是自定義注解UniqueTitle
,第二個(gè)是正在驗(yàn)證的字段類型(在本例中為String
). 我們還自動(dòng)裝配了PostRepository
類以從數(shù)據(jù)庫(kù)中檢索帖子。
isValid()
方法通過(guò)查詢 PostRepository
來(lái)檢查 title
是否為 null 或者它是否是唯一的。如果 title
為 null 或唯一,則驗(yàn)證成功,并返回 true。
定義了自定義驗(yàn)證注釋和驗(yàn)證器類后,我們現(xiàn)在可以使用它來(lái)驗(yàn)證 Spring Boot 應(yīng)用程序中的帖子標(biāo)題:
public class Post {
@UniqueTitle
private String title;
@NotNull
private String body;
}
我們已將 @UniqueTitle
注釋?xiě)?yīng)用于 Post
類中的 title
變量。驗(yàn)證此字段時(shí),這將觸發(fā) UniqueTitleValidator
類中定義的驗(yàn)證邏輯。
3 在服務(wù)器端驗(yàn)證
除了前端或者客戶端做了驗(yàn)證意外,服務(wù)器端驗(yàn)證輸入是至關(guān)重要的。它可以確保在處理或存儲(chǔ)任何惡意或格式錯(cuò)誤的數(shù)據(jù)之前將其捕獲,這對(duì)于應(yīng)用程序的安全性和穩(wěn)定性至關(guān)重要。
假設(shè)我們有一個(gè)允許用戶創(chuàng)建新帳戶的 REST
端點(diǎn)。端點(diǎn)需要一個(gè)包含用戶用戶名和密碼的 JSON 請(qǐng)求體。為確保輸入有效,我們可以創(chuàng)建一個(gè) DTO(數(shù)據(jù)傳輸對(duì)象)類并將驗(yàn)證注釋?xiě)?yīng)用于其字段:
public class UserDTO {
@NotBlank
private String username;
@NotBlank
private String password;
}
我們使用@NotBlank
注解來(lái)確保username
和password
字段不為空或 null。
接下來(lái),我們可以創(chuàng)建一個(gè)控制器方法來(lái)處理 HTTP POST 請(qǐng)求并在創(chuàng)建新用戶之前驗(yàn)證輸入:
@RestController
@RequestMapping("/users")
@Validated
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity
我們使用 Spring 的@Validated
注解來(lái)啟用方法級(jí)驗(yàn)證,我們還將 @Valid
注釋?xiě)?yīng)用于 userDto
參數(shù)以觸發(fā)驗(yàn)證過(guò)程。
-
參數(shù)
+關(guān)注
關(guān)注
11文章
1791瀏覽量
32111 -
校驗(yàn)
+關(guān)注
關(guān)注
0文章
41瀏覽量
12630 -
spring
+關(guān)注
關(guān)注
0文章
338瀏覽量
14312 -
Boot
+關(guān)注
關(guān)注
0文章
149瀏覽量
35787
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論