【27-业务开发-基础业务-品牌管理-图片管理-添加修改品牌信息并显示图片-前端数据校验-后端数据JSR303校验实现-统一异常处理-自定义响应编码规则-分组校验-自定义校验注解-项目Bug解决】

一.知识回顾

【0.三高商城系统的专题专栏都帮你整理好了,请点击这里!】
【1-系统架构演进过程】
【2-微服务系统架构需求】
【3-高性能、高并发、高可用的三高商城系统项目介绍】
【4-Linux云服务器上安装Docker】
【5-Docker安装部署MySQL和Redis服务】
【6-Git安装与配置过程、Gitee码云上创建项目、IDEA关联克隆的项目】
【7-创建商城系统的子模块并将修改后的信息使用Git提交到Gitee上】
【8-数据库表结构的创建&后台管理系统的搭建】
【9-前端项目的搭建部署、Node安装、VSCode安装】
【10-Node的安装以及全局环境变量的相关配置&解决启动报错的问题(1.Error: Cannot find module ‘fs/promises)(2.npm安装node-sass报错)】
【11-导入人人generator项目并自动生成相关的文件&商品子模块的调试&公共模块common子模块的抽离与实现&Lombok插件的安装】
【12-商品子模块整合MyBatisPlus技术&其它模块通过generator的自动生成与补充完善】
【13-项目中微服务组件的学习-SpringCloudAlibaba微服务生态体系的学习&SpringCloudAlibaba的依赖管理&项目中SpringBoot和SpringCloud版本的统一】
【14-微服务的注册中心与配置中心Nacos&Windows操作系统上安装Nacos和Linux操作系统上用Docker中安装Nacos&每个子项目模块使用Nacos进行服务注册与发现】
【15-项目中服务的远程调用之OpenFeign&订单模块与商品模块集成使用OpenFeign的案例】
【16-配置中心之Nacos的基本使用&Nacos服务之命令空间、Nacos服务之配置组、Nacos服务之配置拆分】
【17-微服务网关之Spring Cloud Gateway&Spring Cloud Gateway网关服务搭建】
【18-业务开发-基础业务-商品模块-分类管理-前后端管理系统的启动-为分类管理表增加数据-Json插件的下载-返回具有层级目录、父子关系结构的数据】
【19-业务开发-基础业务-商品模块-分类管理-管理系统新建菜单-后端项目renren注册到Nacos注册中心和配置中心去-项目gateway网关模块的搭建-浏览器的同源策略与解决跨域问题实操案例】
【20-业务开发-基础业务-商品模块-分类管理-前端展示后端具有层级关系的目录数据-商品系统三级分类的逻辑删除前后端代码实现】
【21-业务开发-基础业务-商品模块-分类管理-商品系统三级分类的新增类别前后端代码实现-商品系统三级分类的更新类别前后端代码实现-之前错误的Bug修正】
【22-业务开发-基础业务-商品模块-分类管理-商品系统三级分类拖拽页面的功能-前后端代码的逻辑实现-访问测试-拖拽开关的开启和关系-批量更新拖拽数据-批量删除选定数据】
【23-业务开发-基础业务-品牌管理-品牌管理项目搭建-品牌管理实现的增删改查操作测试-后端数据显示状态使用前端组件开关按钮展示-以及数据处理以及测试】
【24-业务开发-基础业务-品牌管理-图片管理-阿里云OSS服务开通和使用-阿里云OSS服务API使用-SpringCloudAlibaba OSS服务的使用】
【25-业务开发-基础业务-品牌管理-图片管理-图片上传方式的三种实现方式-第三方公共服务模块集成到项目中-服务端生成签名实战】
【26-业务开发-基础业务-品牌管理-图片管理-上传图片功能实现-基于阿里云OSS服务-解决跨域问题-设置跨域规则-修改ACL权限为公共读】

二.添加修改品牌信息并显示图片

前端实现状态按钮的数据绑定,如果不设置默认是true和false,但是我们后台存储的数据是1和0,所以需要提前设置。
在这里插入图片描述

图片上传处理完成后我们就可以实现品牌数据的添加和修改操作

在这里插入图片描述

提交后的数据在table中显示的是logo在阿里云的图片地址,我们需要把图片展示出来
在这里插入图片描述

我们需要修改前端代码
在这里插入图片描述

成功显示,搞定
在这里插入图片描述
阿里云OSS上成功上传图片
在这里插入图片描述

三.前端数据校验

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

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

在这里插入图片描述

前端页面校验的显示
在这里插入图片描述

四.后端数据校验

4.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 中填充一部分

在这里插入图片描述

@NotNull注解、@NotEmpty注解、@NotBlank注解三个注解的区别

@NotNull:不能为null,但可以为empty
@NotEmpty:不能为null,而且长度必须大于0
@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0

4.2 后端校验逻辑实现

如果我们后端没有检验规则,前端通过postman发一些不符合要求的数据依然可以成功,所以说我们在后端添加相关的校验规则是必须的。

  1. 需要在mall-commons服务中添加对应的依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.4.12</version>
</dependency>
  1. 在需要校验的Bean的字段头部添加对应的注解

在这里插入图片描述

  1. 通过@Valid注解来开启JSR303的校验
    在这里插入图片描述

  2. 提交测试通过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) {
                // 获取非法数据的 field
                String 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();
    }

6.然后在BrandEntity实现类中完善其他字段校验规则

@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 品牌id
	 */
	@TableId
	private 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;

}

7.测试访问,提交不符合要求的数据,不允许通过
在这里插入图片描述

4.3 统一的异常处理

4.3.1 统一异常处理我们通过@RestControllerAdvice

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

/**
 * 统一的异常处理类
 * 1:指定包下的异常处理类
 * @RestControllerAdvice(basePackages = "com.ljw.mall.product.controller")
 * 2:RestControllerAdvice---->ResponseBody+ControllerAdvice
 */
/*@ResponseBody
@ControllerAdvice*/
@Slf4j
@RestControllerAdvice(basePackages = "com.ljw.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());
    }


结果展示:
在这里插入图片描述

4.3.2 自定义响应编码规则

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

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

10:表示通用

/001:参数格式错误 10001

/002:未知异常 10002

11:商品

12:订单

13:物流

14:会员

因为后面其它模块都会使用,所以需要在mall-commons模块中定义对应的枚举类

package com.ljw.common.exception;

/**
 * 错误编码和错误信息的枚举类
 */
public enum BizCodeEnum{

    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;
    }
}

在这里插入图片描述

4.3.3 使用自定义响应编码

在统一异常处理中我们就使用自定义的编码
在这里插入图片描述

话不多少,测试看效果
在这里插入图片描述

4.3.4 将上面的代码移动到commons目录下
4.3.4.1 目的
  1. 为了之后其它项目的复用
  2. 便于更好的维护和管理
    在这里插入图片描述
4.3.4.2 需要更新的步骤

mall-commons下导入相关依赖

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

mall-gateway必须排除web的依赖

<!--依赖我们的commons-->
<dependency>
    <groupId>com.ljw.mall</groupId>
    <artifactId>mall-commons</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <exclusions>
        <exclusion>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </exclusion>
    </exclusions>
</dependency>

配置扫描注解
在这里插入图片描述

4.4 分组校验

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

1.在mall-commons->exception->group->定义增加和修改的标志类

在这里插入图片描述

2.指定实体类校验规则

在这里插入图片描述

3.通过@Validated注解来实现增加和修改分组校验
设置增加校验规则
在这里插入图片描述
同理,设置修改校验规则
在这里插入图片描述

4.启动项目,通过postman测试访问验证校验规则
增加品牌信息测试
在这里插入图片描述
修改品牌测试
在这里插入图片描述

存在多种测试方案,根据我们定义的规则测试即可
在这里插入图片描述

4.5 自定义校验注解

先来补充一下:
补充一下:将我们之前定义在exception下的group包移动到valid包下,都是校验的逻辑代码实现,之后便于管理与维护。
在这里插入图片描述


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

1.创建valid包,然后自定义的校验注解ListValue

/**
 * 自定义的校验注解
 */
@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {

    String message() default "{com.ljw.common.valid.ListValue.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

    int[] val() default {};
}

创建提示信息的属性文件

在这里插入图片描述

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

/**
 * 对应的校验注解的校验器
 */
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
    private HashSet<Integer> set = new HashSet<>();

    /**
     * 初始化的方法
     * 举例:@ListValue(val={1,0})
     * 获取到 1 0
     * @param constraintAnnotation
     */
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] val = constraintAnnotation.val();// 0 1
        for (int i : val) {
            set.add(i);
        }
    }

    /**
     * 判断校验是否成功的方法
     * @param value 客户端传递的对应的属性的值 判断value是否在0 , 1 中
     * @param context
     * @return
     */
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return set.contains(value);
    }
}

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

在这里插入图片描述
4.在我们的BrandEntity实体类属性上添加我们自定义的校验注解,并进行增加和更新的分组校验
在这里插入图片描述

5.启动项目,通过postman提交请求,测试是否可行

显示状态不能为null测试成功
在这里插入图片描述

给定一个[0,1]状态之外的结果2,测试成功,但是有点不足之处是出现了乱码
在这里插入图片描述

自定义注解文件提示出现乱码解决方案

自定义注解文件提示出现乱码解决方案:
在这里插入图片描述
重新启动后再次访问测试,如果成功,就可以,如果还不行,就算了,直接改成英文提示吧,自己可以看懂就可以。
在这里插入图片描述
再次测试成功,搞定
在这里插入图片描述

五.串联前后端的项目,解决一个小Bug

问题1:解决之前写正则表达式匹配的一个小问题
在这里插入图片描述
问题2:前端数据校验有个问题
在这里插入图片描述

好了,关于【27-业务开发-基础业务-品牌管理-图片管理-添加修改品牌信息并显示图片-前端数据校验-后端数据JSR303校验实现-统一异常处理-自定义响应编码规则-分组校验-自定义校验注解-项目Bug解决】就先学习到这里,更多内容持续创作学习中,敬请期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值