使用了 jsr303校验,hutool断言,
<!--Hutool工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.4</version>
</dependency>
jsr303校验不用导入依赖,web依赖集成了
直接上代码
hutool断言,通常我用在查询数据库返回结果判断
jsr303用在前端传入的参数校验!
//hutool判断String类型
Assert.notBlank(canvasAllID,"ID不能为空");
//判断一个对象是否为Null
Assert.notNull(canvasTools,"数据不存在");
Hutool更多用法:
isTrue 是否True
isNull 是否是null值,不为null抛出异常
notNull 是否非null值
notEmpty 是否非空
notBlank 是否非空白符
notContain 是否为子串
notEmpty 是否非空
noNullElements 数组中是否包含null元素
isInstanceOf 是否类实例
isAssignable 是子类和父类关系
state 会抛出IllegalStateException异常
Jsr303常用注解:
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内
讲述一下@validated和@valid区别:
在检验Controller的入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同:
嵌套:
public class Song {
@NotNull(message = "id不能为空")
@Min(value = 1, message = "id必须为正整数")
private Long id;
@NotNull(message = "singers不能为空")
@Size(min = 1, message = "至少要有一个属性")
private List<Singer> singers;
}
Singer有自己的校验规则 如果Song 只有@NotNull和@Size 那么Singer里面的属性就没法校验
public class Singer{
@NotNull(message = "id不能为空")
@Min(value = 1, message = "id必须为正整数")
private Long id;
@NotNull(message = "vid不能为空")
@Min(value = 1, message = "vid必须为正整数")
private Long vid;
@NotBlank(message = "pidName不能为空")
private String pidName;
@NotBlank(message = "vidName不能为空")
private String vidName;
}
@RestController
public class ItemController {
@RequestMapping("/song /add")
public void addSong(@RequestBody @Validated Song song) {
System.out.println(song);
}
}
这里只会校验 singer里面的字段数量和非空校验,不会对singer字段里的Singer实体进行字段验证,也就是@Validated和@Valid加在方法参数前,都不会对参数进行嵌套验证。
Song更新一下代码
public class Song {
@NotNull(message = "id不能为空")
@Min(value = 1, message = "id必须为正整数")
private Long id;
@Valid // 嵌套验证必须用@Valid
@NotNull(message = "singers不能为空")
@Size(min = 1, message = "至少要有一个属性")
private List<Singer> singers;
}
@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制
@Validated:只能用在类、方法和方法参数上 ,不能用在字段上!
@Valid:作为标准JSR-303规范,不会进行分组校验,直接校验字段
新增或修改的时候就需要进行分组校验
@Data
@TableName("hss_equipment")
public class Equipment implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@NotNull(message = "修改必须指定id",groups = {UpdateGroup.class})//只有在修改的时候才会触发
@Null(message = "新增不能指定id",groups = {AddGroup.class})//只有在新增的时候才会触发
@TableId
private Long Id;
指定两个分组接口 ,不需要实现,这两个接口需要打在接口上面,用于区分
// 添加的分组校验接口
public interface AddGroup {
}
// 修改的分组校验接口
public interface UpdateGroup {
}
使用@Validated指定分组 只有指定了分组的字段才会生效
/**
* 保存
*/
@RequestMapping("/save")
public R save(@Validated({AddGroup.class}) @RequestBody Equipment equipment) {
brandService.save(brand);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@Validated({UpdateGroup.class})@RequestBody Equipment equipment) {
brandService.updateById(brand);
return R.ok();
}
全局异常类 其它异常我会写出文件到F盘
import com.molomessage.message.sys.service.EmailService;
import com.molomessage.message.sys.utils.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.SimpleDateFormat;
/**
* chen
* 2021-
* 全局异常
* 该注解会 适用所有的@RequestMapper() 结合@ExceptionHander 实现全局异常处理
*/
@RestControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
@Autowired
private EmailService emailService;
private final static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
//jsr303校验全局异常
@ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class}) /*定义拦截*/
public R exceptionHandler(HttpServletRequest request, Exception e) {
BindingResult bindingResult = null;
if (e instanceof MethodArgumentNotValidException) {
bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
} else if (e instanceof BindException) {
bindingResult = ((BindException) e).getBindingResult();
}
StringBuffer buffer = new StringBuffer();
//获取全部异常信息
bindingResult.getFieldErrors().forEach(fieldError ->
buffer.append(fieldError.getDefaultMessage() + ","));
return R.error(buffer.toString());
}
//hutool断言全局异常处理
@ExceptionHandler(value = {IllegalArgumentException.class}) /*定义拦截*/
public R hutoolHandler(HttpServletRequest request, Exception e) {
return R.error(e.getMessage());
}
//其它异常信息
@ExceptionHandler(value = Exception.class)
public R exception(Exception e) {
e.printStackTrace();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final String format = sf.format(new java.util.Date());
StackTraceElement[] stackTrace = e.getStackTrace();
//发送邮件内容
StringBuffer buffer = new StringBuffer();
buffer.append("异常类型:" + e + ",\n");
if (e.getMessage() != null) buffer.append("异常原因:" + e.getMessage() + ",\n");
//类名
buffer.append("类名:" + stackTrace[0].getClassName() + ",\n");
//文件名
buffer.append("文件名:" + stackTrace[0].getFileName() + ",\n");
//方法名
buffer.append("方法名:" + stackTrace[0].getMethodName() + ",\n");
//具体哪一行报的错
buffer.append("报错行数:" + stackTrace[0].getLineNumber() + ",\n");
buffer.append(format + "\n");//当前系统时间
buffer.append(" \n");//换行
//发送邮件给管理员
//emailService.emailSend("8048984@qq.com", "业务异常", buffer.toString());
//异常信息写出到文件中
try {
//以追加的形式写入文件中
FileOutputStream stream = new FileOutputStream("F:/logs/java全局异常信息.txt", true);
try {
stream.write(buffer.toString().getBytes());
stream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
return R.error("服务器异常").put("异常类型", e.toString())
.put("异常原因",e.getMessage())
.put("异常文件名", stackTrace[0].getFileName())
.put("异常方法名", stackTrace[0].getMethodName())
.put("异常行数", stackTrace[0].getLineNumber());
}
}
自定义返回类
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据
*
* @author chen
* @date 2021年
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R() {
put("success",true);
put("code", 0);
put("msg","操作成功");
}
public static R error() {
return error(500, "未知异常,请联系管理员");
}
public static R error(String msg) {
return error(500, msg);
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
r.put("success",false);
return r;
}
public static R ok(String msg, Object obj) {
R r = new R();
r.put("success",true);
r.put("msg", msg);
r.put("data", obj);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("success",true);
r.put("msg", msg);
return r;
}
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
public static R ok() {
return new R();
}
public R put(String key, Object value) {
super.put(key, value);
return this;
}
}
如有错误 请指正!