SpringBoot 参数检验Assert使用
Posted liuec1002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot 参数检验Assert使用相关的知识,希望对你有一定的参考价值。
前言
assert:断言是java的一个保留字,用来对程序进行调试,后接逻辑运算表达式,如下:
int a = 0, b = 1;
assert a == 0 && b == 0;
使用方法:javac编译源文件,再java -ea class文件名即可。
在springboot中可以使用spring提供的Assert类的方法对前端来的参数进行校验
Assert断言基本上替换传统的if判断,减少业务参数校验的代码行数,提高程序可读性。
前面介绍了Validator框架,还需要Assert吗?
Validator只解决了参数自身的数据校验,解决不了参数和业务数据之间校验
举例:
@PostMapping(value = "/test")
public ResponseStandard test(@Validated @RequestBody User user)
//通过用户名 查询用户
User user1 = getUser(user);
Assert.notNull(user1, "用户不存在(Assert抛出)");
return ResponseStandard.successResponse("成功");
User getUser(User user)
return null;
此处user不为空,valiad校验通过,但通过用户名查询,本地用户不存在,为业务校验,抛出异常同时
Assert代码更优雅,更简洁,同样也能实现效果。
详细代码Assert 处理全局异常:
全局处理异常类
import com.andon.springbootdistributedlock.domain.ResponseStandard;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
/**
* 2021/11/10
* <p>
* 全局异常处理器
*/
@Slf4j
@RestControllerAdvice //对Controller增强,并返回json格式字符串
public class GlobalExceptionHandler
/**
* 捕获Exception异常,并自定义返回数据
*/
@ExceptionHandler(Exception.class)
public ResponseStandard<Object> exception(Exception e, HttpServletRequest request)
log.error("request error!! method: uri:", request.getMethod(), request.getRequestURI());
log.error(getExceptionDetail(e));
return ResponseStandard.builder().code(-1).message(request.getMethod() + " " + request.getRequestURI() + " " + e.getMessage()).build();
/**
* Assert异常
*/
@ExceptionHandler(IllegalArgumentException.class, IllegalStateException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseStandard<Object> exception(IllegalArgumentException e,HttpServletRequest request)
log.error("request error!! method: uri:", request.getMethod(), request.getRequestURI());
String message = getExceptionDetail(e);
String message1 = e.getMessage();
return ResponseStandard.failureResponse(e.getMessage(),100);
/**
* 获取代码报错详细位置信息
*/
public String getExceptionDetail(Exception e)
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(e.getClass()).append(System.getProperty("line.separator"));
stringBuilder.append(e.getLocalizedMessage()).append(System.getProperty("line.separator"));
StackTraceElement[] arr = e.getStackTrace();
for (StackTraceElement stackTraceElement : arr)
stringBuilder.append(stackTraceElement.toString()).append(System.getProperty("line.separator"));
return stringBuilder.toString();
返回结果类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ResponseStandard<T> implements Serializable
private int code;
private String message;
private T data;
private int total;
public static <T> ResponseStandard<T> successResponse(T t)
ResponseStandard<T> response = new ResponseStandard<>();
response.setCode(0);
response.setMessage("success!!");
response.setData(t);
response.setTotal(0);
return response;
public static <T> ResponseStandard<T> failureResponse(T t)
ResponseStandard<T> response = new ResponseStandard<>();
response.setCode(-1);
response.setMessage("failure!!");
response.setData(t);
response.setTotal(0);
return response;
public static <T> ResponseStandard<T> failureResponse(String msg,int code)
ResponseStandard<T> response = new ResponseStandard<>();
response.setCode(code);
response.setMessage(msg);
response.setData(null);
response.setTotal(0);
return response;
controller
/**
* @author liu
* @date 2022年05月25日 8:58
*/
@Slf4j
@RequestMapping(value = "/ex")
@RestController
public class TestExceptionController
@PostMapping(value = "/test")
public ResponseStandard test(@Validated @RequestBody User user)
//通过用户名 查询用户
User user1 = getUser(user);
Assert.notNull(user1, "用户不存在(Assert抛出)");
return ResponseStandard.successResponse("成功");
User getUser(User user)
return null;
@Data
public class User
@NotBlank(message = "名字为必填项")
String name;
@Length(min = 8, max = 12, message = "password长度必须位于8到12之间")
String psd;
异常抛出流程:
-
//通过用户名 查询用户
User user1 = getUser(user);结果为null
2. Assert.notNull(user1, “用户不存在(Assert抛出)”); 点进源码:public static void notNull(@Nullable Object object, String message) if (object == null) throw new IllegalArgumentException(message);
抛出IllegalArgumentException
-
全局异常拦截 ` /**
- Assert异常
*/
@ExceptionHandler(IllegalArgumentException.class, IllegalStateException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseStandard exception(IllegalArgumentException e,HttpServletRequest request)
log.error(“request error!! method: uri:”, request.getMethod(), request.getRequestURI());
String message = getExceptionDetail(e);
String message1 = e.getMessage();
return ResponseStandard.failureResponse(e.getMessage(),100);
`
ExceptionHandler 拦截IllegalArgumentException 异常 返回ResponseStandard
- Assert异常
Assert都有哪些方法
对象和类型断言
函数 | 说明 |
---|---|
notNull() | 假设对象不null |
isNull() | 检查对象为null |
isInstanceOf() | 检查对象必须为另一个特定类型的实例 |
isAssignable() | 检查类型 |
文本断言
函数 | 说明 |
---|---|
hasLength() | 检查字符串不是空符串,意味着至少包含一个空白,可以使用hasLength()方法 |
hasText() | 增强检查条件,字符串至少包含一个非空白字符,可以使用hasText()方法 |
doesNotContain() | 检查参数不包含特定子串 |
逻辑断言
函数 | 说明 |
---|---|
isTrue() | 条件为假抛出IllegalArgumentException 异常 |
state() | 该方法与isTrue一样,但抛出IllegalStateException异常 |
Collection和map断言
函数 | 说明 |
---|---|
Collection应用notEmpty() | Collection不是null并包含至少一个元素 |
map应用notEmpty() | 检查map不null,并至少包含一个entry(key,value键值对) |
数组断言
函数 | 说明 |
---|---|
notEmpty() | 可以检查数组不null,且至少包括一个元素 |
noNullElements() | 确保数组不包含null元素 |
SpringBoot - 使用Assert校验让业务代码更简洁
文章目录
Pre
SpringBoot - 优雅的实现【自定义参数校验】高级进阶
SpringBoot - 优雅的实现【参数分组校验】高级进阶
SpringBoot - 使用Assert校验让业务代码更简洁
有了Validator框架,还要Assert干啥子
简而言之 Validator只解决了参数自身的数据校验,解决不了参数和业务数据之间校验
我们来看个例子
/**
* @author 小工匠
* @version 1.0
* @mark: show me the code , change the world
*/
@RestController
@Slf4j
@RequestMapping("/assert")
public class ArtisanController
@Autowired
private ArtisanDao artisanDao;
/**
* Validator只解决了参数自身的数据校验,解决不了参数和业务数据之间校验
*
* @param
* @return
*/
@PostMapping("/testNoAssert")
public void testNoAssert(@RequestParam("artisanId") String artisanId)
Artisan artisan = artisanDao.selectArtisanReturnNull(artisanId);
if (artisan == null)
throw new IllegalArgumentException("用户不存在");
非空判断,大家都很熟悉哈
那用Assert怎么写呢?
/**
* Validator只解决了参数自身的数据校验,解决不了参数和业务数据之间校验
*
* @param
* @return
*/
@PostMapping("/testWithAssert")
public void testWithAssert(@RequestParam("artisanId") String artisanId)
Artisan artisan = artisanDao.selectArtisanReturnNull(artisanId);
Assert.notNull(artisan, "用户不存在(Assert抛出)");
是不是发现Assert代码更优雅,更简洁,同样也能实现效果 .
Assert断言基本上替换传统的if判断,减少业务参数校验的代码行数,提高程序可读性,点赞~~~
大家都在用,随便一找,不信你看
【返回结果】
我们看下
抛出的是 IllegalArgumentException,所以全局异常处理一下
/**
* Assert异常
*/
@ExceptionHandler(IllegalArgumentException.class, IllegalStateException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseData<String> exception(IllegalArgumentException e)
return ResponseData.fail(ResponseCode.ILLEGAL_ARGUMENT.getCode(), e.getMessage());
当然了,我这个返回结果是被全局异常处理了的,如果没有全局异常处理,返回的是原生的这种错误
org.springframework.util.Assert
我们看下Assert都有哪些方法
简单分下类
对象和类型断言
函数 | 说明 |
---|---|
notNull() | 假设对象不null |
isNull() | 检查对象为null |
isInstanceOf() | 检查对象必须为另一个特定类型的实例 |
isAssignable() | 检查类型 |
文本断言
函数 | 说明 |
---|---|
hasLength() | 检查字符串不是空符串,意味着至少包含一个空白,可以使用hasLength()方法 |
hasText() | 增强检查条件,字符串至少包含一个非空白字符,可以使用hasText()方法 |
doesNotContain() | 检查参数不包含特定子串 |
逻辑断言
函数 | 说明 |
---|---|
isTrue() | 条件为假抛出IllegalArgumentException 异常 |
state() | 该方法与isTrue一样,但抛出IllegalStateException异常 |
Collection和map断言
函数 | 说明 |
---|---|
Collection应用notEmpty() | Collection不是null并包含至少一个元素 |
map应用notEmpty() | 检查map不null,并至少包含一个entry(key,value键值对) |
数组断言
函数 | 说明 |
---|---|
notEmpty() | 可以检查数组不null,且至少包括一个元素 |
noNullElements() | 确保数组不包含null元素 |
源码
https://github.com/yangshangwei/boot2
以上是关于SpringBoot 参数检验Assert使用的主要内容,如果未能解决你的问题,请参考以下文章