Spring Boot 對參數進行校驗

在後臺對前端提交的參數驗證是必須的。Spring Boot 內置了相關參數校驗。

1、添加依賴

使用的是Spring Boot 2.7版本,經過測試需要安裝  spring-boot-starter-validation 依賴。如果 pom 沒有從 parent 繼承,需要添加版本號。

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2、 @RequestParam註解參數校驗

前後端參數提交的方式很多,一般使用 @RequestParam ,@RequestBody註解自動獲取參數,有關這兩者的區別參考:SpringBoot中使用註解@RequestParam與 @RequestBody區別

對@RequestParam的參數校驗如下:

controller上添加 @Validated 註解參數前添加對應註解。

@Validated
@RestController
@RequestMapping("/load")
public class PayloadController {
    @PostMapping("manage")
    public ResponseWrapper postEarthStation(
            @RequestParam("id") @Min(0) @Max(127) int id,
            ......
            
    ) {
        ......return reply.equals("success") ? ResponseWrapper.success : ResponseWrapper.fail;
    }
}

3、@RequestBody註解參數校驗

@RequestBody 一般對 content-type: application/json 類型的參數進行校驗,需要定義一個實體類,字段和前端參數需要一一對應。

定義實體類,並對實體類字段進行校驗。

public class TmParamEntity {
    @NotNull(message = "satId字段不能爲空")
    private int satId;
  
    ......  
}

需要添加兩個註解:  controller加上@Validated註解參數前添加@Valid註解。

@Validated
@RestController
@RequestMapping("tele")
public class TelemetryController {
    @PostMapping("postData")
    public ResponseWrapper postTmData(@RequestBody @Valid List<TmParamEntity>  tmParamEntity, HttpServletRequest httpServletRequest) {
        ......
        return ResponseWrapper.success;

    }
}

需要注意的是,如果前端傳遞參數是一個對象,那麼參數類型就是實體類型,如果前端傳遞的是一個數組Array,這裏需要使用 List<TmParamEntity> 類型。添加 @Valid註解,即可使參數校驗生效。參數的反序列化工作,Spring 內置了Jackson 自動處理。如果字段沒對上,會報錯。

4、直接讀取InputStream 

有時我們需要無需藉助 Jackson反序列化,直接從 httpServletRequest 拿到參數,有兩種方法:

InputStreamReader inputStreamReader = new InputStreamReader(httpServletRequest.getInputStream());
char[] chars = new char[1024];
StringBuilder stringBuilder = new StringBuilder();
while ((inputStreamReader.read(chars)) != -1) {
    stringBuilder.append(new String(chars).trim());
}
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader bufferedReader = httpServletRequest.getReader()) {
    String lineString = bufferedReader.readLine();
    while (lineString != null) {
        stringBuilder.append(lineString);
        lineString = bufferedReader.readLine();
    }
}

前者從  InputStreamReader 中讀,後者直接從 BufferedReader  中讀數據。需要注意的是,無論是哪種讀取方式,stream數據只能讀一次。例如使用了Jackson,再用 bufferedReader 去讀,返回的是個null。注意到使用了try(resource) 對網絡資源進行釋放。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章