【业务功能篇78】微服务-前端后端校验- 统一异常处理-JSR-303-validation注解

5. 前端校验

我们在前端提交的表单数据,我们也是需要对提交的数据做相关的校验的

Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可

image.png

校验的页面效果

image.png

前端数据校验就搞定了。后端校验也是不可避免的

6. 后端服务校验

6.1 JSR-303介绍

  JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

  JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。
  Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。

在这里插入图片描述

Hibernate 中填充一部分

在这里插入图片描述

6.2 后端校验实现

1.需要在commons服务中添加对应的依赖

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

2.在需要校验的Bean的字段头部添加对应的注解

image.png

3.通过@Valid注解来开启JSR303的校验

image.png

4.测试,通过postman提交空的数据

image.png

当我们提交一个非空的数据是可以通过的

image.png

5.校验不合法的提示信息,在Controller中通过 BindingResult对象来获取校验的结果信息,然后解析出来后封装为R对象响应

    @RequestMapping("/save")//@RequiresPermissions("product:brand:save")public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){if(result.hasErrors()){// 提交的数据经过JSR303校验后有非法的字段Map<String,String> map = new HashMap<>();List<FieldError> fieldErrors = result.getFieldErrors();for (FieldError fieldError : fieldErrors) {// 获取非法数据的 fieldString field = fieldError.getField();// 获取非法的field的提示信息String defaultMessage = fieldError.getDefaultMessage();map.put(field,defaultMessage);}return R.error(400,"提交的品牌表单数据不合法").put("data",map);}brandService.save(brand);return R.ok();}

image.png

然后完善其他字段你的校验规则

@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 品牌id*/@TableIdprivate Long brandId;/*** 品牌名*///@NotEmpty//@NotNull@NotBlank(message = "品牌的名称不能为空")private String name;/*** 品牌logo地址*/@NotBlank(message = "logo不能为空")@URL(message = "logo必须是一个合法URL地址")private String logo;/*** 介绍*/private String descript;/*** 显示状态[0-不显示;1-显示]*/private Integer showStatus;/*** 检索首字母*/@NotBlank(message = "检索首字母不能为空")@Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字母必须是单个的字母")private String firstLetter;/*** 排序*/@NotNull(message = "排序不能为null")@Min(value = 0,message = "排序不能小于0")private Integer sort;}

image.png

6.3 统一的异常处理

  在SpringMVC中的统一异常处理我们通过ControllerAdvice来处理

/*** 统一的异常处理类*/
/*@ResponseBody
@ControllerAdvice*/
@Slf4j
@RestControllerAdvice(basePackages = "com.msb.mall.product.controller")
public class ExceptionControllerAdvice {/*** 处理验证异常的方法* @param e*/@ExceptionHandler(value = MethodArgumentNotValidException.class)public R handlerValidExecption(MethodArgumentNotValidException e){Map<String,String> map = new HashMap<>();e.getFieldErrors().forEach((fieldError)->{map.put(fieldError.getField(),fieldError.getDefaultMessage());});return R.error(400,"提交的数据不合法").put("data",map);}/*** 系统其他的异常处理* @param throwable* @return*/@ExceptionHandler(Throwable.class)public R handlerExecption(Throwable throwable){log.error("错误信息:",throwable);return R.error(400,"未知异常信息").put("data",throwable.getMessage());}
}

响应编码的规制制订,因为随着后面的业务越来越复杂,我们在响应异常信息的时候尽量准确的给客户端有用的提示信息。

通用的错误列表,响应的编码统一为5位数字,前面两位约定为业务场景,最后三位约定为错误码

10:表示通用

/001:参数格式错误 10001

/002:未知异常 10002

11:商品

12:订单

13:物流

14:会员

定义对应的枚举类

package com.msb.common.exception;/*** 错误编码和错误信息的枚举类*/
public enum BizCodeEnume {UNKNOW_EXCEPTION(10000,"系统未知异常"),VALID_EXCEPTION(10001,"参数格式异常");private int code;private String msg;BizCodeEnume(int code,String msg){this.code = code;this.msg = msg;}public int getCode(){return code;}public String getMsg(){return msg;}
}

在统一异常处理中我们就可以使用通用的编码

package com.msb.mall.product.exception;import com.msb.common.exception.BizCodeEnume;
import com.msb.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
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.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;/*** 统一的异常处理类*/
/*@ResponseBody
@ControllerAdvice*/
@Slf4j
@RestControllerAdvice(basePackages = "com.msb.mall.product.controller")
public class ExceptionControllerAdvice {/*** 处理验证异常的方法* @param e*/@ExceptionHandler(value = MethodArgumentNotValidException.class)public R handlerValidExecption(MethodArgumentNotValidException e){Map<String,String> map = new HashMap<>();e.getFieldErrors().forEach((fieldError)->{map.put(fieldError.getField(),fieldError.getDefaultMessage());});//return R.error(400,"提交的数据不合法").put("data",map);return R.error(BizCodeEnume.VALID_EXCEPTION.getCode(), BizCodeEnume.VALID_EXCEPTION.getMsg()).put("data",map);}/*** 系统其他的异常处理* @param throwable* @return*/@ExceptionHandler(Throwable.class)public R handlerExecption(Throwable throwable){log.error("错误信息:",throwable);//return R.error(400,"未知异常信息").put("data",throwable.getMessage());return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(), BizCodeEnume.UNKNOW_EXCEPTION.getMsg()).put("data",throwable.getMessage());}
}

image.png

6.4 分组校验

  在实际的业务场景中同一个Entity的校验可能会有不同的规则,比如添加数据品牌id必须为空,而更新数据品牌Id必须不为空,针对这种情况我们需要使用分组校验来实现

1>定义标志类

image.png

2>在Entity中指定分组规则

image.png

3>通过@Validated注解来实现分组校验

image.png

6.5 自定义校验注解

  面临特殊的校验需要我们可以通过正则表达式来处理,当然我们也可以通过自定义校验注解的方式来实现。

1> 创建自定义的校验注解

/*** 自定义的校验注解*/
@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {String message() default "{com.msb.common.valid.ListValue.message}";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };int[] val() default {};
}

对应需要创建提示信息的属性文件

image.png

2>创建一个自定义的校验器

package com.msb.common.valid;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.sql.ClientInfoStatus;
import java.util.HashSet;/*** 对应的校验注解的校验器*/
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {private HashSet<Integer> set = new HashSet<>();/*** 初始化的方法* 举例:@ListValue(val={1,0})* 获取到 1 0* @param constraintAnnotation*/@Overridepublic void initialize(ListValue constraintAnnotation) {int[] val = constraintAnnotation.val();// 0 1for (int i : val) {set.add(i);}}/*** 判断校验是否成功的方法* @param value 客户端传递的对应的属性的值 判断value是否在0 , 1 中* @param context* @return*/@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {return set.contains(value);}
}

3>关联自定义的校验注解和校验器

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/110310.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超越界限:大模型应用领域扩展,探索文本分类、文本匹配、信息抽取和性格测试等多领域应用

超越界限&#xff1a;大模型应用领域扩展&#xff0c;探索文本分类、文本匹配、信息抽取和性格测试等多领域应用 随着 ChatGPT 和 GPT-4 等强大生成模型出现&#xff0c;自然语言处理任务方式正在逐步发生改变。鉴于大模型强大的任务处理能力&#xff0c;未来我们或将不再为每…

每天一道leetcode:542. 01 矩阵(图论中等广度优先遍历)

今日份题目&#xff1a; 给定一个由 0 和 1 组成的矩阵 mat &#xff0c;请输出一个大小相同的矩阵&#xff0c;其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 示例1 输入&#xff1a;mat [[0,0,0],[0,1,0],[0,0,0]] 输出&#xff…

Hadoop HA模式切换

Hadoop HA模式下 主从的切换&#xff08;操作命令&#xff09; YARN HA 获取所有RM节点的状态 yarn rmadmin -getAllServiceState获取 rm1 节点的状态 yarn rmadmin -getServiceState rm1手动将 rm1 的状态切换到STANDBY yarn rmadmin -transitionToStandby rm1 ##或者 y…

网络防御和入侵检测

网络防御和入侵检测是维护网络安全的关键任务&#xff0c;可以帮助识别和阻止未经授权的访问和恶意行为。以下是一些基本的步骤和方法&#xff0c;用于进行网络防御和入侵检测。 网络防御&#xff1a; 防火墙设置&#xff1a; 部署防火墙来监控和控制网络流量&#xff0c;阻止…

c# modbus CRC计算器(查表法)

一、简介&#xff1a; 本案例为crc计算器&#xff0c;通过查表法计算出结果 1.窗体后台源代码 using Crc; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text…

修改Jupyter Notebook默认打开路径

这里我是重新下载的anaconda&#xff0c;打开Jupyter之后是默认在C盘的一个路径的&#xff0c;现在我们就来修改一下它的一个默认打开路径&#xff0c;这样在我们后续学习过程中&#xff0c;可以将ipynb后缀的文件放在这个目录下就能查看了。 1、先打开Anaconda Prompt&#x…

数据库第十七课-------ETL任务调度系统的安装和使用

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

商城-学习整理-集群-K8S-集群环境部署(二十四)

目录 一、MySQL集群1、mysql集群原理2、Docker安装模拟MySQL主从复制集群1、下载mysql镜像2、创建Master实例并启动3、创建 Slave 实例并启动4、为 master 授权用户来同步数据1、进入 master 容器2、进入 mysql 内部 &#xff08;mysql –uroot -p&#xff09;3、查看 master 状…

脱离束缚:数字化工厂中ARM控制器的革命性应用!

近年来&#xff0c;中国数字经济体系已进入高速增长阶段。制造业作为中国经济高质量发展的重要支撑力量&#xff0c;在面临生产成本不断上涨、关键装备和核心零部件“受制于人”等挑战时&#xff0c;建设数字化工厂已成必然。 数字化工厂数据采集出现的问题 在数字工厂的建设…

M1 Pro 利用docker 搭建pytho2的开发环境,以vscode连接开发为例

使用 M1 Pro &#xff08;不支持python2的安装&#xff09;开发&#xff0c;需要使用 Python 2.7 的环境&#xff0c;在使用 pyenv 安装 Python 2 时遇到了各种奇怪的问题。最终&#xff0c;我决定使用 Docker 搭建开发环境&#xff0c;并使用 VS Code 连接到本地容器。以下是详…

使用Angular和MongoDB来构建具有登录功能的博客应用程序

Angular 是一个一站式框架&#xff0c;用于使用相同的可重用代码创建移动和 Web 应用程序。使用 Angular&#xff0c;您可以将整个应用程序划分为可重用的组件&#xff0c;从而更轻松地维护和重用代码。 在本教程系列中&#xff0c;您将学习如何开始使用 Angular 和 MongoDB 作…

这是一条求助贴(postman测试的时候一直是404)

看到这个问题是404的时候总感觉不该求助大家&#xff0c;404多常见一看就是简单的路径问题&#xff0c;我的好像不是&#xff0c;我把我的问题奉上。 首先我先给出我的url http://10.3.22.195:8080/escloud/rest/escloud_contentws/permissionStatistics/jc-haojl/sz 这是我…

部队物资仓库管理系统|DW-S301是一套成熟系统

根据军队物资装备管理的实际需求&#xff0c;集驰电子设计了部队物资仓库管理系统&#xff08;智装备&#xff1a;DW-S301&#xff09;。 随着军事装备物资的使用频率与消耗数量日益增加&#xff0c;部队对于仓库保障工作的要求越来越高&#xff0c;同时也带来仓库管理工作任务…

Excel·VBA二维数组组合函数、组合求和

目录 1&#xff0c;二维数组组合函数举例 2&#xff0c;组合求和 之前的文章《ExcelVBA数组组合函数、组合求和》和《ExcelVBA数组排列函数》&#xff0c;都是针对一维数组的组合和排列 二维数组组合&#xff1a;对一个m行*n列的二维数组&#xff0c;每行抽取1个元素进行组合&a…

0基础学习VR全景平台篇 第92篇:智慧景区-智慧景区常见问题

Q&#xff1a;怎么编辑景区里面各个景点的介绍和推荐该景点A&#xff1a;在下方素材栏中该景点&#xff08;素材&#xff09;的右上角选择【编辑场景】里面就可以在场景介绍中编辑该场景的介绍并且在该选项中可以将此场景设置为推荐景点。 Q&#xff1a;景区项目可不可以离线浏…

计算机网络MTU和MSS的区别

在计算机网络中&#xff0c;MTU代表最大传输单元&#xff08;Maximum Transmission Unit&#xff09;&#xff0c;而MSS代表最大分节大小&#xff08;Maximum Segment Size&#xff09;。 1.MTU&#xff08;最大传输单元&#xff09;&#xff1a; MTU是指在网络通信中&#x…

VS+Qt 自定义Dialog

与QtCreator不同&#xff0c;刚用VS添加Qt Dialog界面有点懵&#xff0c;后整理了下&#xff1a; 1.右击项目&#xff0c;选择“添加-模块”&#xff0c;然后选择“Qt-Qt Widgets Class” 2.选择基类[1]QDialog,更改[2]ui文件名称&#xff0c;修改定义Dialog[3]对应类名&#…

超时取消订单

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

【校招VIP】校招考点之前端安全和注入

考点介绍&#xff1a; 随着前端的快速发展&#xff0c;各种技术不断更新&#xff0c;前端的安全问题也越来越值得我们重视。千万不要等到项目上线之后才去重视安全问题&#xff0c;到时候被黑客攻击一切都太晚了。今天的专题将讲述前端几大常见安全问题&#xff0c;在校招面试中…

解决ubuntu文件系统变成只读的方法

所欲文件变成只读&#xff0c;这种情况一般是程序执行发生错误&#xff0c;磁盘的一种保护措施 使用fsck修复 方法一&#xff1a; # 切换root sudo su # 修复磁盘错误 fsck -t ext4 -v /dev/sdb6 方法二&#xff1a; fsck.ext4 -y /dev/sdb6 重新用读写挂载 上面两种方法&…