实战分析:SpringBoot项目 JSR303校验Hutool工具类的具体使用
Posted ABin-阿斌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实战分析:SpringBoot项目 JSR303校验Hutool工具类的具体使用相关的知识,希望对你有一定的参考价值。
我是 ABin-阿斌:写一生代码,创一世佳话,筑一览芳华。 如果小伙伴们觉得文章有点 feel ,那就点个赞再走哦。
声明:
-
原文地址:https://blog.csdn.net/weixin_51216079/article/details/120413239
-
原文作者:CSDN:Coder-CT
文章目录
一、前言
- 在日常开发当中我们会做很多的业务校验,那么我们如果将这些异常有效的返回到页面去跟用户做交互呢?下面我们可以具体卡看看比较常用的几个校验工具。
二、正文
Hutool 相关
- 引入 Hutool 依赖
<!--Hutool工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.4</version>
</dependency>
代码举例
- 具体我们可以直接点击到:Assert 断言内部看源码,都是中文注释。基本上看一眼就会了,还是比较简单的。
- 当然 Hutool 不单单是用来做断言校验,这个工具类的功能是非常丰富的。 更加详细用法可看官网:Hutool官网
PsMessageRelease messageFloodControl = this.getById(messageId);
Assert.isTrue(ObjectUtils.isNotEmpty(messageFloodControl), "ID为:,的详情信息不存在!", messageId);
PsMessageRelease one = this.getOne(Wrappers.lambdaQuery(PsMessageRelease.class)
.eq(PsMessageRelease::getTitle, query.getTitle())
.eq(PsMessageRelease::getDeleteStatus, DeleteConstant.NOT_DEL)
.last(MybatisPlusConst.LIMIT_1));
Assert.isNull(one, "信息主题不可重复!");
JSR303 相关
- JSR303 校验不用导入依赖,web 依赖集成了,JSR303 我们一般用来做一些入参的校验。
代码举例
- 更多相关 API 操作我们可以看官网:JSR303 官网
@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();
全局异常类
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;
以上是关于实战分析:SpringBoot项目 JSR303校验Hutool工具类的具体使用的主要内容,如果未能解决你的问题,请参考以下文章