当前位置: 首页 > news >正文

validate校验的使用

目录

1.说明

2.RequestParam及PathVariable示例

3.RequestBody示例

4.总结


1.说明

后端接收前端传递的参数时,需要进行校验处理,最常用的就是非空校验,前端传递的内容不能为空。

2.RequestParam及PathVariable示例

①依赖

        <!--        参数校验--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>

② 校验代码

package com.example.demo2.controller;import com.example.demo2.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import java.util.Set;@RestController
@RequestMapping("/validate")
@Validated
public class ValidateController {@Autowiredprivate Validator validator;@GetMapping("/test1")public String test1(@RequestParam @Min(value = 10, message = "id不能小于10") Long id,@RequestParam @NotBlank(message = "name不能为空") String name) {return "test1";}@GetMapping("/test5/{id}")public String test5(@PathVariable @Min(value = 10, message = "id不能小于10") Long id) {return "test5";}@GetMapping("/test2")public String test2(@RequestParam Long id,@RequestParam String name) {SysUser sysUser = new SysUser().setUserId(id).setUserName(name);Set<ConstraintViolation<SysUser>> validate = validator.validate(sysUser);if (!CollectionUtils.isEmpty(validate)) {throw new ConstraintViolationException(validate);}return "test2";}}
package com.example.demo2.domain;import lombok.Data;
import lombok.experimental.Accessors;import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import java.util.Date;/*** 用户对象 sys_user*/
@Data
@Accessors(chain = true)
public class SysUser
{private static final long serialVersionUID = 1L;/** 用户ID */@Min(value = 10, message = "id不能小于10")private Long userId;/** 部门ID */private Long deptId;/** 用户账号 */@NotBlank(message = "name不能为空")private String userName;/** 用户昵称 */private String nickName;/** 用户邮箱 */private String email;/** 手机号码 */private String phonenumber;/** 用户性别 */private String sex;/** 用户头像 */private String avatar;/** 密码 */private String password;/** 帐号状态(0正常 1停用) */private String status;/** 删除标志(0代表存在 2代表删除) */private String delFlag;/** 最后登录IP */private String loginIp;/** 最后登录时间 */private Date loginDate;}

③实现方式

实现方式一

  1. 在类上需要添加@Validated
  2. 在参数中添加校验注解
  3. 抛出ConstraintViolationException异常,通过全局异常处理校验的异常

实现方式二

  1. 注入Validator
  2. 将参数传递至实体类中
  3. 在实体类的属性上添加校验注解
  4. 调用Validator的validate方法进行校验,将实体类作为参数
  5. 判断返回值是否为空,不为空,抛出ConstraintViolationException校验异常,方通过全局异常进行处理

3.RequestBody示例

①依赖同上

②示例

package com.example.demo2.controller;import com.example.demo2.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import java.util.Set;@RestController
@RequestMapping("/validate")
public class ValidatePostController {@Autowiredprivate Validator validator;@PostMapping("/test3")public String test3(@RequestBody @Validated SysUser sysUser) {return "test3";}@PostMapping("/test4")public String test4(@RequestBody SysUser sysUser) {Set<ConstraintViolation<SysUser>> validate = validator.validate(sysUser);if (!CollectionUtils.isEmpty(validate)) {throw new ConstraintViolationException(validate);}return "test4";}}
package com.example.demo2.domain;import lombok.Data;
import lombok.experimental.Accessors;import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import java.util.Date;/*** 用户对象 sys_user*/
@Data
@Accessors(chain = true)
public class SysUser
{private static final long serialVersionUID = 1L;/** 用户ID */@Min(value = 10, message = "id不能小于10")private Long userId;/** 部门ID */private Long deptId;/** 用户账号 */@NotBlank(message = "name不能为空")private String userName;/** 用户昵称 */private String nickName;/** 用户邮箱 */private String email;/** 手机号码 */private String phonenumber;/** 用户性别 */private String sex;/** 用户头像 */private String avatar;/** 密码 */private String password;/** 帐号状态(0正常 1停用) */private String status;/** 删除标志(0代表存在 2代表删除) */private String delFlag;/** 最后登录IP */private String loginIp;/** 最后登录时间 */private Date loginDate;}

全局异常处理

package com.example.demo2.globalException;import com.example.demo2.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;/*** 全局异常处理器*/
@RestControllerAdvice
public class GlobalExceptionHandler {private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 处理业务异常*/@ExceptionHandler(BusinessException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public AjaxResult handleBusinessException(BusinessException e, HttpServletRequest request) {log.error("业务异常:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());return AjaxResult.error(e.getMessage());}/*** 处理参数校验异常*/@ExceptionHandler(IllegalArgumentException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public AjaxResult handleIllegalArgumentException(IllegalArgumentException e, HttpServletRequest request) {log.error("参数校验异常:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());return AjaxResult.error("参数错误:" + e.getMessage());}/*** 处理请求方法不支持异常*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)public AjaxResult handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {log.error("不支持的请求方法:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());return AjaxResult.error("不支持的请求方法:" + e.getMethod());}/*** 处理参数缺失异常*/@ExceptionHandler(MissingServletRequestParameterException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public AjaxResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e, HttpServletRequest request) {log.error("缺少请求参数:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());return AjaxResult.error("缺少必要的请求参数:" + e.getParameterName());}/*** 处理参数类型不匹配异常*/@ExceptionHandler(MethodArgumentTypeMismatchException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {log.error("参数类型不匹配:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());return AjaxResult.error("参数类型不匹配:" + e.getName());}/*** 处理参数绑定异常*/@ExceptionHandler(BindException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public AjaxResult handleBindException(BindException e, HttpServletRequest request) {log.error("参数绑定异常:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());return AjaxResult.error("参数绑定失败:" + e.getBindingResult().getFieldError().getDefaultMessage());}/*** 处理参数校验异常* 在请求中直接使用@Validated注解对请求体进行校验,会抛出此异常,不能在类上添加@Validated,必须在请求中添加*/@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public AjaxResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {log.error("参数校验异常:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());String errorInfo = e.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(";"));return AjaxResult.error("参数校验失败:" + errorInfo);}/*** 处理约束违反异常(@Max、@Min、@Valid等直接在参数上的校验)* 处理get请求及post请求的请求地址中的参数校验,需要在整个controller中添加注解@Validated,然后在每个参数后面添加内容校验的注解,如notnull,min等等* 在service中直接注入private Validator validator;当校验结果不为空时,也可以抛出ConstraintViolationException异常*/@ExceptionHandler(ConstraintViolationException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public AjaxResult handleConstraintViolationException(ConstraintViolationException e, HttpServletRequest request) {log.error("约束违反异常:请求地址:{},异常信息:{}", request.getRequestURI(), e.getMessage());// 提取所有的约束违反信息String errorMessage = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("; "));return AjaxResult.error("参数校验失败:" + errorMessage);}/*** 处理所有不可知的异常* 注意:这个处理器要放在最后,因为Exception是所有异常的父类*/@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public AjaxResult handleException(Exception e, HttpServletRequest request) {log.error("系统异常:请求地址:{},异常信息:", request.getRequestURI(), e);return AjaxResult.error("系统错误,请联系管理员");}
//     主要改进和完善包括:
// 异常分类更细致:
// 业务异常(BusinessException)
// 参数校验异常(IllegalArgumentException)
// 请求方法不支持异常(HttpRequestMethodNotSupportedException)
// 参数缺失异常(MissingServletRequestParameterException)
// 参数类型不匹配异常(MethodArgumentTypeMismatchException)
// 参数绑定异常(BindException)
// 参数校验异常(MethodArgumentNotValidException)
// 约束违反异常(ConstraintViolationException)
// 系统异常(Exception)
// 添加了HTTP状态码:
// 使用@ResponseStatus注解指定不同的HTTP状态码
// 业务异常和参数异常返回400(BAD_REQUEST)
// 请求方法不支持返回405(METHOD_NOT_ALLOWED)
// 系统异常返回500(INTERNAL_SERVER_ERROR)
// 完善了日志记录:
// 添加了请求地址信息
// 区分了不同类型的异常日志
// 使用更详细的日志格式
// 异常处理最佳实践:
// 保持异常处理方法的顺序(从具体到通用)
// 统一的返回格式(使用AjaxResult)
// 清晰的错误信息
// 适当的HTTP状态码
// 其他建议:
// 考虑添加异常监控和告警机制
// 敏感信息不要直接返回给前端
// 可以根据环境(开发/生产)返回不同详细程度的错误信息
// 考虑添加异常统计和性能监控
// 这样的全局异常处理更加完善,能够处理更多类型的异常,并提供更好的日志记录和错误信息。
}

 ③实现方式

方式一

  1. 在参数中添加@Validated注解,不能添加在类上
  2. 在实体类中添加校验注解
  3. 抛出MethodArgumentNotValidException异常,通过全局异常进行处理

方式二

同上

4.总结

①通过validate及全局校验处理,实现参数校验

可以采用方式二,抛出ConstraintViolationException,进行统一的处理

②全局异常处理在开发中很常见,在spring mvc中如果没有配置全局异常处理,会转发到/error(注意是服务端内部转发,非客户端重定向,浏览器地址栏不会变)。),就可能会执行spring mvc的拦截器处理导致发生一些问题,可以配置全局异常处理来避免这种问题

相关文章:

  • 50、文件上传-单文件与多文件上传的使用
  • 使用大模型预测巨细胞病毒视网膜炎的技术方案
  • JavaScript 标签加载
  • QT 第三讲 --- 基础篇 初用信号槽与命名规范
  • tomcat组件架构设计
  • 【仿生机器人】建模—— 图生3D 的几个办法
  • 2020年IS SCI2区,多样本和遗忘能力粒子群算法XPSO,深度解析+性能实测
  • 阿里云服务状态监控:实时掌握云服务健康状况
  • 基于cornerstone3D的dicom影像浏览器 第三十一章 从PACS服务加载图像
  • 生态系统服务(InVEST模型)供给与需求、价值核算技术及人类活动、重大工程项目、自然保护区、碳中和等
  • 如何在网页里填写 PDF 表格?
  • 免费在线PDF转图片工具
  • XXE漏洞知识
  • 免费PDF转图片软件
  • 学习 Hooks【Plan - June - Week 2】
  • 免费PDF转图片工具
  • 在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
  • 一桩多用:新能源汽车智慧充电桩的多元化智能管理方案
  • 深入理解 S3 标签字符清洗的正则表达式实践
  • 解决ubuntu20.04无法唤醒的问题的一种方法
  • 晋城网络公司做网站的/营销公司取名字大全
  • 晋中路桥建设集团网站/最新疫情最新消息
  • 做推广网站公司/免费域名怎么注册
  • 湘潭网站优化公司/合肥网站推广电话
  • 平顶山哪里做网站/怎样做百度推广
  • 做赌博网站刷单违法吗/seo营销推广服务公司