异常处理总结

自定义异常

​ 系统中的异常可以分为我们能预知的异常和未知的系统异常,对于我们能预知的异常如空值判断,用户名错误,密码错误等异常我们需要返回客户端,对于系统内部异常如SQL语法错误,参数格式转换错误等需要统一包装成友好的提示后再返回客户端,否则用户也看不懂系统内部的异常。

定义响应码ResponseCode ,方便之后的自定义异常

public enum ResponseCode {
    RESPONSE_CODE_200(200, "操作成功"),
    RESPONSE_CODE_400(400, "参数错误"),
    RESPONSE_CODE_1001(1001, "激活失败已过期"),
    RESPONSE_CODE_1002(1002, "密码不一致")

    private Integer code;
    private String message;
    
    ResponseCode(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

定义已知异常BusinessException,用于区分项目中的已知异常和未知异常


public class BusinessException extends RuntimeException{
    private Integer code;

    public BusinessException(ResponseCode responseCode) {
        super(responseCode.getMessage());
        this.code = responseCode.getCode();
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public BusinessException() {
        super();
    }

    public BusinessException(String s) {
        super(s);
    }

    public BusinessException(String message, Throwable cause) {
        super(message, cause);
    }

    public BusinessException(Throwable cause) {
        super(cause);
    }

    protected BusinessException(String message, Throwable cause,
                                boolean enableSuppression,
                                boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

自定义断言工具类,避免大量if判断

public class AssertUtils {

    public static void isTrue(Boolean flag, ResponseCode responseCode) {
        if (!flag) {
            throw new BusinessException(responseCode);
        }
    }

    public static void isBlank(String str, ResponseCode responseCode) {
        if (StrUtil.isNotBlank(str)) {
            throw new BusinessException(responseCode);
        }
    }

    public static void isNotBlank(String str, ResponseCode responseCode) {
        if (StrUtil.isBlank(str)) {
            throw new BusinessException(responseCode);
        }
    }

    public static void isNull(Object object, ResponseCode responseCode) {
        if (Objects.nonNull(object)) {
            throw new BusinessException(responseCode);
        }
    }

    public static void isNotNull(Object object, ResponseCode responseCode) {
        if (Objects.isNull(object)) {
            throw new BusinessException(responseCode);
        }
    }

    public static void isNull(Collection collection, ResponseCode responseCode) {
        if (collection != null && !collection.isEmpty()) {
            throw new BusinessException(responseCode);
        }
    }

    public static void isNotNull(Collection collection, ResponseCode responseCode) {
        if (collection == null || collection.isEmpty()) {
            throw new BusinessException(responseCode);
        }
    }

    public static void isEq(String str1, String st2, ResponseCode responseCode) {
        if (!str1.equals(st2)) {
            throw new BusinessException(responseCode);
        }
    }


    public static void isEqIgnoreCase(String str1, String str2, ResponseCode responseCode) {
        if (!str1.equalsIgnoreCase(str2)) {
            throw new BusinessException(responseCode);
        }
    }

    public static void smallerThan(Long second, int i, ResponseCode responseCode) {
        if (second > i) {
            throw new BusinessException(responseCode);
        }
    }
}

全局异常处理类,不再写大量try - catch,由全局异常处理类自动捕获

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public AjaxResult businessExceptionHandler(BusinessException e) {
        e.printStackTrace();
        return AjaxResult.me()
                .setSuccess(false)
                .setMessage(e.getMessage())
                .setCode(e.getCode());
    }
	
	//JSR-303校验所抛出的异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public AjaxResult MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        e.printStackTrace();
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        StringBuffer sb = new StringBuffer();
        allErrors.forEach(objectError -> sb.append(objectError.getDefaultMessage()).append("! "));
        return AjaxResult.me()
                .setSuccess(false)
                .setMessage(sb.toString())
                .setCode(ResponseCode.RESPONSE_CODE_400.getCode());
    }

    @ExceptionHandler(Exception.class)
    public AjaxResult ExceptionHandler(Exception e) {
        e.printStackTrace();
        return AjaxResult.me()
                .setSuccess(false)
                .setMessage(ResponseCode.RESPONSE_CODE_500.getMessage())
                .setCode(ResponseCode.RESPONSE_CODE_500.getCode());
    }
}

在使用dto接受前端参数时,可以使用JSR-303校验

@Data
public class PlaceOrderDTO {

    private String parentOrderNo;

    @NotNull(message = "请选择收货地址") // 当为空时会报错 -> "请选择收货地址"
    private OrderGiftAddress address;

}

可以将异常信息定义在properties中在resources包下ValidationMessages.properties配置文件中,将中文转换为Unicode转义序列的UTF-16编码格式

example.error.blank     = \u4e0d\u80fd\u4e3a\u7a7a
\u4e0d 表示中文字符“不”。
\u80fd 表示中文字符“能”。
\u4e3a 表示中文字符“为”。
\u7a7a 表示中文字符“空”。

ValidationMessages.properties配置文件原本是在org.hibernate.validator包下的,因为javaapi中只定义了jsr303规范,具体实现是由其他包实现的,springboot-starter下是由org.hibernate.validator来实现的

@NotBlank(message = "${example.error.blank}")
   private String username;
    

在controller接口参数位置打上@Valid,JSR303才能生效

 @PostMapping("/placeorder")
    public AjaxResult placeOrder(@Valid @RequestBody PlaceOrderDTO dto) {
        orderGiftService.placeOrder(dto);
        return AjaxResult.me().setResultObj(dto.getUniPayOrderSn());
    }
    ```

相关推荐

  1. 异常处理总结

    2024-06-18 23:36:03       8 阅读
  2. 后端异常处理:全局异常处理器

    2024-06-18 23:36:03       25 阅读
  3. springBoot异常总结

    2024-06-18 23:36:03       9 阅读
  4. 题目 异常处理

    2024-06-18 23:36:03       34 阅读

最近更新

  1. 精通C#编程需要学习哪些常用框架?

    2024-06-18 23:36:03       1 阅读
  2. Redis高可用解决方案哨兵模式与集群模式的比较

    2024-06-18 23:36:03       1 阅读
  3. C#实用的工具类库

    2024-06-18 23:36:03       1 阅读
  4. 4085行代码还原2D我的世界(上)

    2024-06-18 23:36:03       1 阅读
  5. 大数据面试题之GreenPlum(1)

    2024-06-18 23:36:03       2 阅读
  6. 量化机器人能否识别市场机会?

    2024-06-18 23:36:03       1 阅读
  7. 探讨SpringMVC的工作原理

    2024-06-18 23:36:03       1 阅读
  8. CSS布局艺术:掌握水平与垂直对齐的秘诀

    2024-06-18 23:36:03       1 阅读

热门阅读

  1. AQS和同步器工具类

    2024-06-18 23:36:03       7 阅读
  2. 微信小程序-路由和页面跳转API

    2024-06-18 23:36:03       7 阅读
  3. 算法设计与分析

    2024-06-18 23:36:03       8 阅读
  4. 定义仅限关键字参数

    2024-06-18 23:36:03       8 阅读
  5. NumPy 切片和索引

    2024-06-18 23:36:03       7 阅读
  6. 关于CSS

    关于CSS

    2024-06-18 23:36:03      5 阅读
  7. TOP150-LC121-买卖股票的最佳时机

    2024-06-18 23:36:03       6 阅读
  8. CSS 表单设计指南

    2024-06-18 23:36:03       5 阅读
  9. Samba服务访问异常分析处理

    2024-06-18 23:36:03       6 阅读
  10. 华为OD机试 C++ - 生日礼物

    2024-06-18 23:36:03       8 阅读