SpringBoot + validation 接口参数校验的思路详解

网友投稿 313 2022-11-16


SpringBoot + validation 接口参数校验的思路详解

有参数传递的地方都少不了参数校验。在web开发中,前端的参数校验是为了用户体验,后端的参数校验是为了安全。试想一下,如果在controller层中没有经过任何校验的参数通过service层、dao层一路来到了数据库就可能导致严重的后果,最好的结果是查不出数据,严重一点就是报错,如果这些没有被校验的参数中包含了恶意代码,那就可能导致更严重的后果。

实践

一、引入依赖

org.springframework.boot

spring-boot-starter-validation

二、使用校验

在controller层的参数校验可以分为两种场景:

单个参数校验

实体类参数校验

2.1 单参数校验

/**

* 参数校验测试 控制类

* @author oyc

*/

@RestController

@RequestMapping("user")

@Validated

public class RequestParamsValidatedController {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@GetMapping

public User test(@NotNull(message = "姓名不能为空") String name,

@NotNull(message = "年龄不能为空") @Max(value = 99, message = "不能大于200岁") Integer age) {

logger.info("name:" + name + " -age:" + age);

return new User(name, age);

}

}

2.2 实体类参数校验

/**

* 参数校验测试 控制类

* @author oyc

*/

@RestController

@RequestMapping("user")

@Validated

public class RequestParamsValidatedController {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@PostMapping

public User http://save(@Validated User user) {

logger.info(user.toString());

return user;

}

}

package com.oycbest.springbootvalidated.vo;

import javax.validation.constraints.*;

import java.io.Serializable;

/**

* 用户实体类

* @author oyc

*/

public class User implements Serializable {

private String userId;

@NotNull(message = "用户名不能为空")

private String userName;

@NotNull(message = "年龄不能为空")

@Max(value = 100, message = "年龄不能大于100岁")

private int age;

@NotNull(message = "邮箱不能为空")

@Email(message = "邮箱格式不正确")

private String email;

@NotNull(message = "电话号码不能为空")

private String phoneNumber;

public User(@NotNull(message = "用户名不能为空") String userName, int age) {

this.userName = userName;

this.age = age;

}

public User() {

}

public User(String userId, @NotNull(message = "用户名不能为空") String userName, int age, String email, String phoneNumber) {

this.userId = userId;

this.userName = userName;

this.agJqzZHDdCe = age;

this.email = email;

this.phoneNumber = phoneNumber;

}

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getEmail() {

reJqzZHDdCturn email;

}

public void setEmail(String email) {

this.email = email;

}

public String getPhoneNumber() {

return phoneNumber;

}

public void setPhoneNumber(String phoneNumber) {

this.phoneNumber = phoneNumber;

}

@Override

public String toString() {

return "User{" +

"userId='" + userId + '\'' +

", userName='" + userName + '\'' +

", age=" + age +

", email='" + email + '\'' +

", phoneNumber='" + phoneNumber + '\'' +

'}';

}

}

2.3 定义统一异常处理

package com.oycbest.springbootvalidated.exception;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.context.annotation.Bean;

import org.springframework.http.HttpStatus;

import org.springframework.stereotype.Component;

import org.springframework.validation.BindException;

import org.springframework.validation.FieldError;

import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ConstraintViolation;

import javax.validation.ConstraintViolationException;

import javax.validation.ValidationException;

import java.util.List;

import java.util.Set;

/**

* 全局异常处理

*

* @author oyc

*/

@ControllerAdvice

@Component

public class GlobalExceptionHandler {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Bean

public MethodValidationPostProcessor methodValidationPostProcessor() {

return new MethodValidationPostProcessor();

}

@ExceptionHandler

@ResponseBody

@ResponseStatus(HttpStatus.BAD_REQUEST)

public String handle(ValidationException exception) {

logger.error("请求异常:" + exception.getMessage());

if (exception instanceof ConstraintViolationException) {

ConstraintViolationException exs = (ConstraintViolationException) exception;

Set> violations = exs.getConstraintViolations();

for (ConstraintViolation> item : violations) {

//打印验证不通过的信息

logger.error("请求异常:" + item.getMessage());

}

}

return "请求异常: " + exception.getMessage();

}

@ResponseBody

@ExceptionHandler(value = BindException.class)

public String bindException(Exception e) {

if (e instanceof BindException) {

BindException exs = (BindException) e;

List fieldErrors = exs.getFieldErrors();

for (FieldError item : fieldErrors) {

logger.error("请求异常:" + item.getDefaultMessage());

}

}

logger.error("数据绑定异常:" + e.getMessage());

return "数据绑定异常";

}

@ResponseBody

@ExceptionHandler(value = Exception.class)

public String defaultException(Exception e) {

logger.error("请求异常:" + e.getMessage());

return "请求异常 " + e.getMessage();

}

}

三、约束性注解(简单)说明

注解

功能

@AssertFalse

可以为null,如果不为null的话必须为false

@AssertTrue

可以为null,如果不为null的话必须为true

@DecimalMax

设置不能超过最大值

@DecimalMin

设置不能超过最小值

@Digits

设置必须是数字且数字整数的位数和小数的位数必须在指定范围内

@Future

日期必须在当前日期的未来

@Past

日期必须在当前日期的过去

@Max

最大不得超过此最大值

@Min

最大不得小于此最小值

@NotNull

不能为null,可以是空

@Null

必须为null

@Pattern

必须满足指定的正则表达式

@Size

集合、数组、map等的size()值必须在指定范围内

@Email

必须是email格式

@Length

长度必须在指定范围内

@NotBlank

字符串不能为null,字符串trim()后也不能等于“”

@NotEmpty

不能为null,集合、数组、map等size()不能为0;字符串trim()后可以等于“”

@Range

值必须在指定范围内

@URL

必须是一个URL


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Maven项目打Jar包并添加依赖步骤详解
下一篇:springboot整合kaptcha生成验证码功能
相关文章

 发表评论

暂时没有评论,来抢沙发吧~