66
1、保存修改页面中更改显示状态信息。激活为1,不激活为0
在 <el-switch>
中,:active-value="1" :inactive-value="0"
2、logo上传成功后,在主页显示数据栏显示图片。用插槽,
<template slot-scope="scope">
<img :src="scope.row.logo" style="width:100px; height:80px">
</template>
3、表单自定义校验器。要求:首字母是一个字母,排序字段为数字
firstLetter: [
{
validator: (rule, value, callback) => {
if (value === "") {
callback(new Error("首字母不能为空"));
} else if (!/^[a-zA-z]$/.test(value)) {
callback(new Error("首字母必须在a-z或者A-Z之间"));
} else {
callback();
}
},
trigger: "blur",
},
],
sort: [{ validator: (rule, value, callback) => {
if (value === "") {
callback(new Error("排序不能为空"));
} else if (!Number.isInteger(value) || value<0) {
callback(new Error("排序必须不小于0"));
} else {
callback();
}
}, trigger: "blur" }],
而且改动 <el-input v-model.number=".....">
4、默认显示状态是1,排序是0。
67 JSR303数据校验
1、导入注解时,注解所在的包名(防止导入错包):
输入查找 @NotNull
查看所在位置:javax.validation.constraints
2、
@NotNull 不能为空,must not be null。支持所有类型
@NotEmpty 不能为空且不能为empty。支持集合类,Array、Collection、Map、字符串CharSequence
@NotBlank 不能为空且至少包含一个字符。支持字符串CharSequence
也就是 private Integer sort;
要求不为空时,必须只能是 @NotNull
3、
(1)给bean添加校验注解,并定义自己的message提示,如 @Email @NotNull
要求:
首字母
@NotBlank
@Pattern(regexp = "^[a-zA-Z]$")
品牌名
@NotBlank
logo地址
@NotBlank
@URL(message = "logo必须是一个合法的URL地址")
排序
@NotNull
@Min(value = 0, message = "排序必须大于等于0")
(2)在controller里面方法保存数据时,开启校验功能。(@Valid…)
效果:校验错误以后会有默认的相应
public R save(@Valid @RequestBody BrandEntity brand, BindingResult result)
(3)在参数后加,给校验后的Bean紧跟 BindingResult result ,就可以获得校验的结果
if(result.hasErrors()){
Map<String, String> map = new HashMap<>();
result.getFieldErrors().forEach(item ->{
// 获取校验结果错误的属性名和错误信息
String message = item.getDefaultMessage();
String field = item.getField();
map.put(field, message);
});
return R.error(400, "提交数据不合法").put("data",map);
}else {
brandService.save(brand);
return R.ok();
}
68 统一异常处理
1、将controller方法内BindingResult 和异常处理部分删除,但是@Valid字段要保留
2、在common模块,建立valid软件包,BizCodeEnum枚举类型。每个不同类型用逗号。
UNKNOWN_EXCEPTION(10000,"系统未知异常"),
VALID_EXCEPTION(10001,"参数格式校验异常");
private int code;
private String msg;
BizCodeEnum(int code, String msg){
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
3、同controller建包exception,建类 GulimailExceptionHandleAdvice.class,注意命名规则。
类名上写由springMvc提供得到@ControllerAdvice处理
---->log打印,类名添加@SLF4j
----->返回类型以json形式,类名添加 @ResponseBody
------>ResponseBody + ControllerAdvice = RestControllerAdvice
ExceptionHandler 感知报错,初始用 Exception.class
初始不知道error具体类型,通过打印 log.error("报错信息为{},异常类型为{}", e.getMessage(), e.getClass())
获取
得到具体的类型后,发现 e 有了方法 getBindingResult()。同之前写法。
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleValidException(MethodArgumentNotValidException e){
BindingResult bindingResult = e.getBindingResult();
HashMap<String, String> map = new HashMap<>();
bindingResult.getFieldErrors().forEach(item->{
map.put(item.getField(), item.getDefaultMessage());
});
return R.error(BizCodeEnum.VALID_EXCEPTION.getCode(), BizCodeEnum.VALID_EXCEPTION.getMsg()).put("data",map);
}
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable){
return R.error(BizCodeEnum.UNKNOWN_EXCEPTION.getCode(), BizCodeEnum.UNKNOWN_EXCEPTION.getMsg());
}
69 JSR303分组校验
品牌id在新增时默认自增,无需提交;但在修改时要求不为空。有不同的要求。
像logo、首字母、排序,新增时不为空,但在修改时允许未更改的数据不进行提交。
用途:标注什么情况下进行校验。
若它没有被分组会怎么样呢?是所有情况都被校验吗? nonono!默认不起作用
1、注解存在参数 groups
2、在common模块,valid软件包下新建 AddGroup 和 UpdateGroup 接口
3、方法save中写明@Validated({AddGroup.class}),同理update
70 自定义校验器
功能:为显示状态定义ListValue(vals={0,1})
只允许保存0和1
校验注解需要满足规范,3个属性 + 元信息数据
3个属性
1、String message() default "{com.atguigu.common.valid.ListValue.message}"
;
出错时的提示信息。需要创建配置文件,自定义配置信息。同名ValidationMessages.properties。
若提示信息文件格式错误,需要删除该文件,取消勾选。在设置----编辑器----文件编码----将properties改为UTF形式,并自动展现。
2、Class<?>[] groups() default { };
支持分组。
3、Class<? extends Payload>[] payload() default { };
自定义负载信息。需要导入
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
额外再加一个int数组 int[] vals() default { };
元信息数据
@Constraint(validatedBy = {ListValueConstraintValidator.class })
使用哪一个校验器获取,可以指定多个不同的校验器,适配不同类型的校验。
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
标注位置。方法、属性、构造器、参数
@Retention(RUNTIME)
时机,运行时获取到
@Repeatabel(List.class)
可重复注解
自定义校验器
class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer>
继承接口,泛型指定注解和校验什么类型数据。
初始化方法 initialize
int[] vals = constraintAnnotation.vals();
for (int val:vals){
set.add(val);
}
判断是否校验成功 isValid
return set.contains(integer);
自定义私有Set
private Set<Integer> set = new HashSet<>();
额外的,在java指定正则时,即检索首字母,^[a-zA-Z]$
,不出现后面的\
因为修改update需要提交品牌名,可在修改状态给一个快速修改的方法,无需品牌名,只品牌ID和显示状态。
新增分组 UpdataStatusGroup.class
@NotNull(groups = {AddGroup.class,UpdataStatusGroup.class})
@ListValue(vals={0,1}, groups = {AddGroup.class,UpdataGroup.class, UpdataStatusGroup.class})
private Integer showStatus;
并在前端页面 updateBrandStatus
修改发送请求