自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

瞧瞧別人家的參數(shù)校驗(yàn),那叫一個(gè)優(yōu)雅!

開發(fā) 前端
在 Spring Boot 中,我們可以使用 Hibernate Validator(Bean Validation 的參考實(shí)現(xiàn))來實(shí)現(xiàn)參數(shù)校驗(yàn)。它的核心思路是:把校驗(yàn)邏輯從業(yè)務(wù)代碼里抽離出來,用注解的方式聲明校驗(yàn)規(guī)則。

前言

對(duì)于開發(fā)人員來說,對(duì)用戶輸入的參數(shù)或者系統(tǒng)參數(shù)做校驗(yàn),是日常工作之一。

很多小伙伴在寫接口的時(shí)候,可能都會(huì)碰到一個(gè)問題:參數(shù)校驗(yàn)應(yīng)該怎么寫?

比如,開發(fā)一個(gè)用戶注冊(cè)接口,需要校驗(yàn)以下條件:

  • 用戶名不能為空,長(zhǎng)度在 3 到 20 個(gè)字符之間;
  • 密碼不能為空,長(zhǎng)度至少為 8 個(gè)字符;
  • 年齡必須是正整數(shù),不能超過 120;
  • 郵箱必須符合標(biāo)準(zhǔn)格式。

乍一看,這種校驗(yàn)邏輯看起來很簡(jiǎn)單嘛,直接寫幾個(gè) if 就完事了。

但真的這么簡(jiǎn)單嗎?

接下來我們就從傳統(tǒng)的參數(shù)校驗(yàn)入手,看看問題出在哪,然后再聊聊 Spring Boot 中如何優(yōu)雅地實(shí)現(xiàn)參數(shù)校驗(yàn),希望對(duì)你會(huì)有所幫助。

一、傳統(tǒng)參數(shù)校驗(yàn)的問題

很多人可能會(huì)直接在 Controller 里手寫校驗(yàn)邏輯,比如下面這個(gè)代碼:

@RestController
@RequestMapping("/api/users")
public class UserController {

    @PostMapping("/register")
    public ResponseEntity<String> register(@RequestBody Map<String, Object> request) {
        String username = (String) request.get("username");
        if (username == null || username.length() < 3 || username.length() > 20) {
            return ResponseEntity.badRequest().body("用戶名不能為空,且長(zhǎng)度必須在3到20之間");
        }

        String password = (String) request.get("password");
        if (password == null || password.length() < 8) {
            return ResponseEntity.badRequest().body("密碼不能為空,且長(zhǎng)度至少為8個(gè)字符");
        }

        Integer age = (Integer) request.get("age");
        if (age == null || age <= 0 || age > 120) {
            return ResponseEntity.badRequest().body("年齡必須是正整數(shù),且不能超過120");
        }

        return ResponseEntity.ok("注冊(cè)成功!");
    }
}

這段代碼乍一看沒什么問題,但如果仔細(xì)分析,會(huì)發(fā)現(xiàn)一堆隱患:

  1. 代碼冗余:校驗(yàn)邏輯散落在 Controller 里,寫起來麻煩,后期維護(hù)更是災(zāi)難。
  2. 重復(fù)勞動(dòng):類似的校驗(yàn)邏輯可能會(huì)出現(xiàn)在多個(gè)接口里,導(dǎo)致代碼重復(fù)度極高。
  3. 用戶體驗(yàn)差:返回的錯(cuò)誤信息不統(tǒng)一、不規(guī)范,前端開發(fā)還得猜用戶輸入到底哪兒錯(cuò)了。
  4. 擴(kuò)展性差:萬一某天需要加新的校驗(yàn)規(guī)則,你可能要到處改代碼。

所以,這種手寫參數(shù)校驗(yàn)的方式,在簡(jiǎn)單場(chǎng)景下勉強(qiáng)能用,但如果業(yè)務(wù)變復(fù)雜,問題會(huì)越來越多。

那么問題來了,那有沒有更優(yōu)雅的方式來處理這些問題呢?

答:當(dāng)然是有的。

二、Spring Boot 的參數(shù)校驗(yàn)機(jī)制

在 Spring Boot 中,我們可以使用 Hibernate Validator(Bean Validation 的參考實(shí)現(xiàn))來實(shí)現(xiàn)參數(shù)校驗(yàn)。

它的核心思路是:把校驗(yàn)邏輯從業(yè)務(wù)代碼里抽離出來,用注解的方式聲明校驗(yàn)規(guī)則。

接下來我們一步步來看怎么實(shí)現(xiàn)。

1. 使用注解進(jìn)行參數(shù)校驗(yàn)

首先,定義一個(gè)用于接收用戶注冊(cè)參數(shù)的 DTO 對(duì)象:

@Data
public class UserRegistrationRequest {

    @NotNull(message = "用戶名不能為空")
    @Size(min = 3, max = 20, message = "用戶名長(zhǎng)度必須在3到20之間")
    private String username;

    @NotNull(message = "密碼不能為空")
    @Size(min = 8, message = "密碼長(zhǎng)度至少為8個(gè)字符")
    private String password;

    @NotNull(message = "年齡不能為空")
    @Min(value = 1, message = "年齡必須是正整數(shù)")
    @Max(value = 120, message = "年齡不能超過120")
    private Integer age;

    @Email(message = "郵箱格式不正確")
    private String email;
}

這里我們用了幾個(gè)常見的校驗(yàn)注解:

  • @NotNull:字段不能為空;
  • @Size:限制字符串長(zhǎng)度;
  • @Min 和 @Max:限制數(shù)值范圍;
  • @Email:校驗(yàn)郵箱格式。

這些注解由 Hibernate Validator 提供,基本涵蓋了日常開發(fā)中的大部分校驗(yàn)需求。

然后,在 Controller 中這樣寫:

@RestController
@RequestMapping("/api/users")
public class UserController {

    @PostMapping("/register")
    public ResponseEntity<String> register(@Valid @RequestBody UserRegistrationRequest request) {
        return ResponseEntity.ok("注冊(cè)成功!");
    }
}

注意這里的 @Valid 注解,它的作用是告訴 Spring:對(duì)請(qǐng)求參數(shù)進(jìn)行校驗(yàn)。

2. 統(tǒng)一處理校驗(yàn)錯(cuò)誤

如果前端傳的參數(shù)不合法,Spring 會(huì)拋出一個(gè) MethodArgumentNotValidException 異常。默認(rèn)情況下,這個(gè)異常返回的信息不太友好,可能是這樣的:

{
  "timestamp": "2024-01-01T12:00:00.000+00:00",
  "status": 400,
  "error": "Bad Request",
  "message": "Validation failed for object='userRegistrationRequest'. Error count: 2",
  "path": "/api/users/register"
}

為了提升用戶體驗(yàn),我們可以用全局異常處理器來統(tǒng)一格式化錯(cuò)誤信息:

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationException(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> {
            errors.put(error.getField(), error.getDefaultMessage());
        });
        return ResponseEntity.badRequest().body(errors);
    }
}

現(xiàn)在,當(dāng)參數(shù)校驗(yàn)失敗時(shí),返回的錯(cuò)誤信息會(huì)變成這樣:

{
  "username": "用戶名長(zhǎng)度必須在3到20之間",
  "password": "密碼不能為空"
}

清晰又直觀,用戶一看就明白自己錯(cuò)在哪兒了。

三、應(yīng)對(duì)復(fù)雜場(chǎng)景的高級(jí)技巧

1. 分組校驗(yàn)

有些場(chǎng)景下,不同的接口對(duì)參數(shù)的校驗(yàn)規(guī)則是不一樣的,比如:

  • 注冊(cè)接口要求 username 和 password 是必填項(xiàng);
  • 更新接口只需要校驗(yàn) email 和 age。

這種情況下,可以用 分組校驗(yàn) 來解決。

定義校驗(yàn)分組

public interface RegisterGroup {}
public interface UpdateGroup {}

在字段上指定分組

public class UserRequest {

    @NotNull(groups = RegisterGroup.class, message = "用戶名不能為空")
    @Size(min = 3, max = 20, groups = RegisterGroup.class, message = "用戶名長(zhǎng)度必須在3到20之間")
    private String username;

    @NotNull(groups = RegisterGroup.class, message = "密碼不能為空")
    private String password;

    @Email(groups = UpdateGroup.class, message = "郵箱格式不正確")
    private String email;

    @Min(value = 1, groups = UpdateGroup.class, message = "年齡必須是正整數(shù)")
    private Integer age;
}

在 Controller 中指定分組

@RestController
@RequestMapping("/api/users")
public class UserController {

    @PostMapping("/register")
    public ResponseEntity<String> register(@Validated(RegisterGroup.class) @RequestBody UserRequest request) {
        return ResponseEntity.ok("注冊(cè)成功!");
    }

    @PutMapping("/update")
    public ResponseEntity<String> update(@Validated(UpdateGroup.class) @RequestBody UserRequest request) {
        return ResponseEntity.ok("更新成功!");
    }
}

2. 自定義校驗(yàn)注解

如果 Hibernate Validator 提供的注解不能滿足需求,還可以自定義校驗(yàn)注解。例如,校驗(yàn)手機(jī)號(hào)格式。

定義注解

@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPhone {
    String message() default "手機(jī)號(hào)格式不正確";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

實(shí)現(xiàn)校驗(yàn)邏輯

public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {

    private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return value != null && value.matches(PHONE_REGEX);
    }
}

使用自定義注解

public class UserRequest {
    @ValidPhone
    private String phone;
}

四、總結(jié)

優(yōu)雅的參數(shù)校驗(yàn)不僅能提高代碼的可維護(hù)性,還能顯著提升用戶體驗(yàn)。

在 Spring Boot 中,通過使用 Hibernate Validator 提供的注解,配合分組校驗(yàn)、自定義校驗(yàn)和統(tǒng)一異常處理。

我們可以輕松實(shí)現(xiàn)簡(jiǎn)潔、高效、可擴(kuò)展的參數(shù)校驗(yàn)機(jī)制。

優(yōu)雅的參數(shù)校驗(yàn)的秘籍是:

  1. 注解優(yōu)先:能用注解解決的校驗(yàn),就不要手寫邏輯代碼。
  2. 分離校驗(yàn)邏輯:參數(shù)校驗(yàn)應(yīng)該集中在 DTO 層,避免散落在業(yè)務(wù)代碼中。
  3. 全局統(tǒng)一異常處理:確保錯(cuò)誤信息規(guī)范化、友好化。
  4. 合理使用分組校驗(yàn):根據(jù)接口需求靈活調(diào)整校驗(yàn)規(guī)則。
  5. 覆蓋邊界條件:通過單元測(cè)試驗(yàn)證校驗(yàn)邏輯,確保沒有漏網(wǎng)之魚。
責(zé)任編輯:武曉燕 來源: 蘇三說技術(shù)
相關(guān)推薦

2024-11-12 08:20:31

2025-04-08 08:20:33

2024-10-24 08:21:33

2022-12-12 08:14:47

2025-03-06 08:21:02

判空entity對(duì)象

2025-04-22 08:20:51

2025-03-11 08:20:58

2025-02-28 08:21:00

2020-11-03 16:00:33

API接口微服務(wù)框架編程語言

2015-09-24 09:22:16

nodejs頁面始末

2017-11-12 21:32:52

戴爾

2016-01-08 09:49:19

DockerDocker案例云應(yīng)用開發(fā)

2020-11-17 09:34:31

API接口后端

2017-09-22 13:22:59

大數(shù)據(jù)南京大學(xué)宿舍

2023-12-30 20:04:51

MyBatis框架數(shù)據(jù)

2021-07-14 06:31:08

京東互聯(lián)網(wǎng)加薪

2021-01-20 05:42:27

RabbitMQMQ vhost

2019-06-11 09:35:50

戴爾

2017-06-13 14:15:51

戴爾協(xié)同計(jì)算汽車神話

2022-09-26 19:10:45

Kafka架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)