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. 使用场景

两种调用都可以:

  1. Postman 调用(前端)
  2. 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. 使用场景

  1. Postman 调用(前端)
  2. Feign 调用异常类是拦截不到异常的,调用端报错。如果调用端对这异常类有处理,便可以使用
image-20230911101255833

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、统一异常

AOP和统一异常处理同时存在open in new window

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();
}