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) 对网络资源进行释放。

 

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