01-请求Exception
1. @RequestBody
1. 被校验的接口
@RequestMapping("/ooxx")
ResultUtil<String> ooxx(@RequestBody @Validated TokenDto tokenDto);
2. 被校验的类
@Data
public class TokenDto {
@NotBlank(message = "token为空")
private String token;
}
3. 异常类
MethodArgumentNotValidException
4. 使用场景
两种调用都可以:
Postman
调用(前端)Feign
调用(后端)
2. @RequestParam
1. @Validated
/**
* @author: lisongtao
* @description: 平台可用性测试
* @create: 2020-09-09 14:00
*/
@Slf4j
@Validated
@RestController
@RequestMapping("/ooxx")
public class Ooxx {
2. @NotBlank
@PostMapping("/ooxx")
ResultUtil<User> ooxx(@RequestParam @NotBlank(message = "loginName为空") String loginName, @RequestParam String authKey);
3. @NotBlank校验异常
ConstraintViolationException
4. 参数缺失异常
MissingServletRequestParameterException
- 只捕捉到缺失的第一个参数,后面都被忽略了
5. 使用场景
Postman
调用(前端)Feign
调用异常类是拦截不到异常的,调用端报错。如果调用端对这异常类有处理,便可以使用
3. 自定义返回异常
1. 自定义异常类
/**
* @author: lisongtao
* @description: ResultException
* @create: 2020-09-29 20:48
*/
public class ResultException extends RuntimeException{
private final Integer status;
private final String message;
public ResultException(Integer status, String message) {
this.status = status;
this.message = message;
}
public Integer getStatus() {
return status;
}
public String getMessage() {
return message;
}
}
2. throw
@Override
public ResultUtil<Boolean> testController(@NotBlank String loginName) {
if (loginName.equals("songsong")) {
throw new ResultException(Enum.S_10017.getStatus(), Enum.S_90305.getMessage());
}
return ResultUtil.success(true);
}
3. 统一处理
/**
* 处理结果异常ResultException
*
* @param e ResultException
* @return ResultUtil<Object>
*/
@ExceptionHandler(ResultException.class)
public ResultUtil<Object> resultExceptionHandler(ResultException e) {
return ResultUtil.result(e.getStatus(), e.getMessage());
}
4. 统一异常处理类
package com.listao.aspect;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
/**
* @author: lisongtao
* @description: GlobalExceptionHandler
* @create: 2020-08-04 11:10
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理@RequestParam form类型请求
*
* @param e ConstraintViolationException(校验异常)
* @return ResultUtil<Object>
*/
@ExceptionHandler(ConstraintViolationException.class)
public ResultUtil<Object> paramCheckExceptionHandler(ConstraintViolationException e) {
return ResultUtil.result(400, this.getResultMessage(e.getConstraintViolations()));
}
/**
* 处理@RequestBody json类型请求
*
* @param e MethodArgumentNotValidException @NotBlank @NotEmpty @Pattern
* @return ResultUtil<Object>
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultUtil<Object> paramCheckExceptionHandler(MethodArgumentNotValidException e) {
return ResultUtil.result(400, this.getResultMessage(e.getBindingResult()));
}
/**
* 处理@RequestParam form类型请求
*
* @param e MissingServletRequestParameterException(参数缺失)
* @return ResultUtil<Object>
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
public ResultUtil<Object> paramCheckExceptionHandler(MissingServletRequestParameterException e) {
return ResultUtil.result(400, "[" + e.getParameterName() + "]为空");
}
/**
* 处理结果异常ResultException
*
* @param e ResultException
* @return ResultUtil<Object>
*/
@ExceptionHandler(ResultException.class)
public ResultUtil<Object> resultExceptionHandler(ResultException e) {
return ResultUtil.result(e.getStatus(), e.getMessage(), e.getData());
}
/**
* 对异常请求消息进行处理
*
* @param bindingResult 返回异常消息
* @return String
*/
private String getResultMessage(BindingResult bindingResult) {
String msg = "";
ObjectError err;
for (Iterator<ObjectError> var2 = bindingResult.getAllErrors().iterator(); var2.hasNext(); msg = msg + "[" + err.getDefaultMessage() + "]") {
err = var2.next();
}
return msg;
}
/**
* 对异常请求消息进行处理
*
* @param constraintViolations 返回异常消息
* @return String
*/
private String getResultMessage(Set<ConstraintViolation<?>> constraintViolations) {
StringBuilder msg = new StringBuilder();
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
msg.append("[").append(constraintViolation.getMessage()).append("]");
}
return msg.toString();
}
}
5. AOP、统一异常
1. AOP处理了异常
异常被捕获,查看请求栈信息,在哪里被捕获的
@Around("startSign()")
public Object around(ProceedingJoinPoint pjp) {
Object[] args = pjp.getArgs();
if (ooxxConfig.getAppSignSwitch() && args.length > 0) {
Object arg = args[0];
Map<String, Object> requestMap = BeanUtil.beanToMap(arg, false, true);
Object secretKey = requestMap.get("secretKey");
Object ot = requestMap.get("ot");
if (secretKey == null || ot == null) {
return ResultUtil.result(400, "请求参数没有签名");
}
requestMap.remove("secretKey");
if (!secretKey.equals(SignUtils.sign(requestMap))) {
return ResultUtil.result(400, "请求参数签名有误");
}
}
try {
return pjp.proceed();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
2. AOP异常抛出
AOP异常抛出,由统一异常统一处理
@Around("startSign()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
if (ooxxConfig.getAppSignSwitch() && args.length > 0) {
Object arg = args[0];
Map<String, Object> requestMap = BeanUtil.beanToMap(arg, false, true);
Object secretKey = requestMap.get("secretKey");
Object ot = requestMap.get("ot");
if (secretKey == null || ot == null) {
return ResultUtil.result(400, "请求参数没有签名");
}
requestMap.remove("secretKey");
if (!secretKey.equals(SignUtils.sign(requestMap))) {
return ResultUtil.result(400, "请求参数签名有误");
}
}
return pjp.proceed();
}