参考element:Element - The world's most popular Vue UI framework
1、自定义图片显示
<el-table-column
prop="logo"
header-align="center"
align="center"
label="品牌logo地址"
>
<template slot-scope="scope">
<!-- <el-image
style="width: 100px; height: 80px"
:src="scope.row.logo"
fit="contain"
></el-image> -->
<img style="width: 100px; height: 80px"
:src="scope.row.logo"
fit="contain">
</template>
</el-table-column>
2、自定义校验排序字段以及检索首字符
validatePass自定义表单校验函数,rule表示表单验证, value传入参数, callback表单验证返回值
:rules="dataRule"定义表单校验
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="140px"
>
<el-form-item label="检索首字母" prop="firstLetter">
<el-input
v-model="dataForm.firstLetter"
placeholder="检索首字母"
></el-input>
</el-form-item>
firstLetter: [
{
validatePass: (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",
},
],
<el-form-item label="排序" prop="sort">
<el-input v-model.number="dataForm.sort" placeholder="排序"></el-input>
</el-form-item>
sort: [
{
validatePass: (rule, value, callback) => {
if (value == "") {
callback(new Error("排序字段必须填写"));
} else if (!Number.isInteger(value) || value>0) {
callback(new Error("排序必须是一个大于零的整数"));
} else {
callback();
}
},
trigger: "blur",
},
],
3、后端JSR303
1)、给Bean添加校验注解:javax.validation.constraints,并定义自己的message提示
2)、开启校验功能@Valid效果:校验错误以后会有默认的响应
3)、给校验的bean后紧跟一个BindingResult,就可以获取到校验的结果
4)、分组校验
1)、@NotBlank(message= "品牌名须提交", groups = AddGroup.class, UpdateGroup.class))给校验注解标注什么情况需要进行校验
2) 、@Validated({AddGroup.class})
3)、默认没有指定分组的校验注解@NotBlank,在分组校验@Validated({AddGroup.class})情况下不生效,只会在@Validated生效;
5)、自定义校验
1)、编写一个自定义的校验注解
2)、编写一个自定义的校验器 ConstraintValidator
3)、关联自定义的校验器和自定义的校验注解
@Documented @Constraint(validatedBy = { ListValueConstraintValidator.class【可以指定多个不同的校验器】}) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) public @interface ListValue {
/**
* 品牌名
*/
@NotBlank(message = "品牌名必须提交")
private String name;
/**
* 品牌logo地址
*/
@NotEmpty
@URL(message = "logo必须是一个合法的url地址")
private String logo;
/**
* 检索首字母
* @Pattern自定义校验
*/
@NotEmpty
@Pattern(regexp = "/^[a-zA-Z]$/", message = "检索首字母必须是一个字母")
private String firstLetter;
/**
* 排序
*/
@NotNull
@Min(value = 0, message = "排序必须大于等于0")
private Integer sort;
/**
* 保存
*/
@RequestMapping("/save")
//@RequiresPermissions("product:brand:save")
public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
if (result.hasErrors()){
Map<String, String> map = new HashMap<>();
//1、获取校验的结果
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();
}
4、分组校验
/**
* 保存
*/
@RequestMapping("/save")
//@RequiresPermissions("product:brand:save")
public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand/*, BindingResult result*/){
// if (result.hasErrors()){
// Map<String, String> map = new HashMap<>();
// //1、获取校验的结果
// 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();
}
/**
* 修改
*/
@RequestMapping("/update")
//@RequiresPermissions("product:brand:update")
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
brandService.updateById(brand);
return R.ok();
}
/**
* 品牌id
*/
@NotNull(message = "修改必须指定品牌id", groups = {UpdateGroup.class})
@Null(message = "新增不能指定id", groups = {AddGroup.class})
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名必须提交", groups = {AddGroup.class,UpdateGroup.class})
private String name;
/**
* 品牌logo地址
*/
@NotEmpty(groups = {AddGroup.class})
@URL(message = "logo必须是一个合法的url地址", groups = {AddGroup.class,UpdateGroup.class})
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
private Integer showStatus;
/**
* 检索首字母
* @Pattern自定义校验
*/
@NotEmpty(groups = {AddGroup.class})
@Pattern(regexp = "/^[a-zA-Z]$/", groups = {AddGroup.class,UpdateGroup.class}, message = "检索首字母必须是一个字母")
private String firstLetter;
/**
* 排序
*/
@NotNull(groups = {AddGroup.class})
@Min(value = 0, message = "排序必须大于等于0", groups = {AddGroup.class,UpdateGroup.class})
private Integer sort;
5、自定义校验注解
校验注解
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.xushuobin.common.valid.ListValue.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] vals() default {};
}
校验器
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> set = new HashSet<>();
//初始化方法
@Override
public void initialize(ListValue constraintAnnotation) {
//ConstraintValidator.super.initialize(constraintAnnotation);
int[] value = constraintAnnotation.vals();
for (int i : value) {
set.add(i);
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
校验字段
/**
* 显示状态[0-不显示;1-显示]
*/
@ListValue(vals = {0, 1}, groups = {AddGroup.class, UpdateGroup.class})
private Integer showStatus;
校验提示
4、统一的异常处理@ControllerAdvice
1)、编写异常处理类,使用@ControllerAdvice.
2)、使用@ExceptionHandler标注方法可以处理的异常。
/***
* 错误码和错误信息定义类
* 1. 错误码定义规则为5为数字
* 2. 前两位表示业务场景,最后三位表示错误码。例如:100001。10:通用 001:系统未知异常
* 3. 维护错误码后需要维护错误描述,将他们定义为枚举形式
* 错误码列表:
* 10: 通用
* 001:参数格式校验
* 11: 商品
* 12: 订单
* 13: 购物车
* 14: 物流
*/
public enum BizCodeEnume {
UNKNOW_EXEPTION(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.xushuobin.gulimall.product.exception;
import com.xushuobin.common.exception.BizCodeEnume;
import com.xushuobin.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestControllerAdvice(basePackages = "com.xushuobin.gulimall.product.controller")
public class GulimallExceptionControllerAdvice {
// 处理数据校验异常
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleVaildException(MethodArgumentNotValidException e){
log.error("数据校验出现问题{},异常类型: {}",e.getMessage(),e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String, String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach((fieldError)->{
errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return R.error(BizCodeEnume.VALID_EXCEPTION.getCode(),BizCodeEnume.VALID_EXCEPTION.getMsg()).put("data", errorMap);
}
//处理全局异常
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable){
return R.error(BizCodeEnume.UNKNOW_EXEPTION.getCode(), BizCodeEnume.UNKNOW_EXEPTION.getMsg());
}
}