分布式项目-品牌管理(7、8、9)

文章讲述了在前后端交互中,如何进行有效的数据校验,包括前端的表单验证,后端的JSR-303注解校验,以及分组校验策略。同时,提到了统一异常处理机制和自定义校验注解的实现,以及SPU和SKU的概念。此外,文章还强调了组件化的思想,将三级分类模块抽取为独立组件以提高复用性。
摘要由CSDN通过智能技术生成

【今日成果】:

//啊哈哈哈 , 莫名其妙入选了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
//相当于 “树表联动(左树右表)” ;
在这里插入图片描述
// 使用el-cascader 。
在这里插入图片描述
//点击修改后三级级联选择框会自动拉取相关数据。
在这里插入图片描述
如果想要能够键盘输入搜索,则需要添加 filterable属性。

【快速回顾】:

(1):
虽然提交表单的时候前端做了校验,但是通过PostMAN接口调试,我们发现不规范的数据还是会被存储到数据库中;——需要做后端校验;
(2):
不能在每一个Controller接口上都加上那么一大堆代码,这个时候就需要使用统一异常处理;
(3):
关于code , 随着后面开发的模块越来越多 , 返回的CODE需要区分开来。——这就涉及到编码规则的制定。
(4):
同一个实体类不同的操作对同一个字段的要求是不同的 , 例如ID , 添加的时候不需要校验 ,但是修改的时候就必须得进行非空判断,这个时候就得使用——分组校验;
(5):
自定义校验注解。
(6):
SKU 和 SPU 。基本属性、销售属性 。
(7):
将《三级分类》模块单独抽取成一个组件 , 方便在其它模块中进行使用;

【具体细节】:

【后端校验】:

(1):传入实体对象后,使用if…else…来逐个字段校验;
(2):使用JSR-303 ;

    /**
     * 保存
     */
    @RequestMapping("/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();
    }

【实体类上的注解信息】:

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

	@TableId
	private Long brandId;

	@NotEmpty(message = "品牌的名称不能为空")
	private String name;

	@URL(message = "logo必须是一个合法的URL地址")
	@NotEmpty(message = "LOGO不能为空")
	private String logo;

	@Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字母必须是单个的字母")
	@NotEmpty(message = "检索首字母不能为空")
	private String firstLetter;

	@Min(value=0 , message = "排序不能小于0")
	@NotNull(message = "排序字段不能为null                                                  ")
	private Integer sort;
}

【统一异常处理】:

通用的错误列表 , 响应的编码统一为5位数字 , 前面两位约定为业务场景 , 最后三位约定为错误码;
10——表示通用;
/001:参数格式错误 10001

/002:未知异常 10002

11:商品

12:订单

13:物流

14:会员

/*
* 错误编码 和 错误信息的枚举类
* */
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;
    }
}

【分组异常处理】:

在这里插入图片描述

	/**
	 * 品牌id
	 */
	@NotNull(message = "更新数据品牌ID必须不为空",groups = {UpdateGroupsInterface.class})
	@Null(message = "添加品牌信息品牌ID必须为空",groups = {AddGroupsInterface.class})
	@TableId
	private Long brandId;

【Controller中的代码】:

在这里插入图片描述

【接口】:

【Update】:

【Add】:

【注意】:

一旦指定了分组,那么没有分组的注解就会失效;
在这里插入图片描述
如果没有红色区域的注解,只有蓝色的注解 , 那么蓝色的注解会起作用;
但是一旦使用了红色区域的注解,那么———蓝色区域的注解就不会再起作用(因为启用了分组);

【自定义校验注解】:

(1):创建自定义的校验注解;

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

    String message() default "提交的数据必须在数据列表中";

    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):关联自定义的校验注解和校验器。
在这里插入图片描述

【SPU】:(类)

标准化产品单元 , 商品信息聚合的最小单位;通俗讲——属性值、特性相同的商品就可以成为一个SPU。

【SKU】:(对象)

库存量单位 , 库存进出计量的单位,可以是以件、盒等为单位。是物理上不可分割的最小存货单元。

【基本属性、销售属性】:

【基本属性】:
SPU对应的属性,也就是SKU他们都有的属性,在JAVA中可以看成static类型的属性,和类绑定;
【销售属性】:
就是SKU特有的属性,在JAVA中可以看成私有的属性,属于对象。
每个分类下的商品共享规格参数和销售属性 , 有些商品不一定要这个分类下的全部的属性。

【 JsonInclude注解 】:

	/**
	* 当前类别所拥有的所有的子类
	* */
	@JsonInclude(JsonInclude.Include.NON_EMPTY)                       //不为空的情况下才包含~~~
	@TableField(exist = false)   //这个字段是在数据库中没有的!!!
	private List<CategoryEntity> childrens;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值