服务端数据校验的重要性就不用多说了,虽然前端也有数据校验,但我们还是要对传入后端的参数再校验一遍,避免一些邪恶的用户直接向服务端发送非法参数。
下面就先通过一个极其简单方便的例子演示springboot中如何进行优雅地参数校验。
maven坐标只需要有spring-boot-starter-web即可,其中已包含了jsr和hibernate validator提供的校验注解
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
直接在控制器的方法中进行参数校验
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.Map;
@RestController
@Validated//这个注解不能少
public class ValidatedController {
@GetMapping("/index")
public String index(@NotBlank(message = "用户名不能为空") @RequestParam("name") String name)
{
return "hello "+name+"from ";
}
//接收到非法参数会抛出异常,由下方的ExceptionHandler接收
@ExceptionHandler(value = Exception.class)
public Map<String,String> exhandler(Exception ex)
{
Map<String,String> error=new HashMap<>();
error.put("code","400");
error.put("msg",ex.getMessage());
return error;
}
}
实体类中的参数校验:
实体类:
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class Person {
@NotBlank(message = "用户们不为空")
@Length(max = 20,message = "用户名长度不超过20")
private String name;
@Size(min = 6,max = 20,message = "密码6-20位")
private String password;
@Email(message = "email格式不正确")
private String email;
...省略get set 和构造器
}
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@RestController
public class ValidatedController {
@PostMapping("/person")
public ResponseEntity<Person> person(@Valid @RequestBody Person person)
{
return ResponseEntity.ok(person);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
//遍历每一条异常字段结果
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return ResponseEntity.badRequest().body(errors);
}
}
JSR提供的校验注解:
-
@Null
被注释的元素必须为 null -
@NotNull
被注释的元素必须不为 null -
@AssertTrue
被注释的元素必须为 true -
@AssertFalse
被注释的元素必须为 false -
@Min(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值 -
@Max(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值 -
@DecimalMin(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值 -
@DecimalMax(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值 -
@Size(max=, min=)
被注释的元素的大小必须在指定的范围内 -
@Digits (integer, fraction)
被注释的元素必须是一个数字,其值必须在可接受的范围内 -
@Past
被注释的元素必须是一个过去的日期 -
@Future
被注释的元素必须是一个将来的日期 -
@Pattern(regex=,flag=)
被注释的元素必须符合指定的正则表达式
Hibernate Validator提供的校验注解:
-
@NotBlank(message =)
验证字符串非null,且长度必须大于0 -
@Email
被注释的元素必须是电子邮箱地址 -
@Length(min=,max=)
被注释的字符串的大小必须在指定的范围内 -
@NotEmpty
被注释的字符串的必须非空 -
@Range(min=,max=,message=)
被注释的元素必须在合适的范围内