SpringBoot-(9)自定义异常和全局异常

自定义异常和全局异常

异常是什么在这里不多做解释了。在实际的项目开发中,程序会发生各种异常,如果这些异常不做处理,将会直接暴露给前端,即暴露给用户,降低体验质量,也留下安全隐患。对可能发生的异常进行处理和日志记录,能保证后端程序的正常运行,也能给用户带来更好的体验。采用全局异常将减少try catch这样重复的异常处理,减少代码量,防止漏网的异常没被处理。

1、自定义异常

1)创建异常枚举类

package com.example.demo.enums;

public class ErrorCode {
    private ErrorCode() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * 我就试一下
     */
    public static final String HELLO_EXCEPTION = "90000001";
    public static final String SERVICE_EXCEPTION = "90000002";
}

2)自定义异常类

package com.example.demo.exceptions;

public class AppServiceException extends Exception{

    private static final long serialVersionUID = -2416380262384957964L;

    /**
     * 错误编码
     */
    private String code;

    public String getCode() {
        return code;
    }

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

    public AppServiceException() {}

    public AppServiceException(final String message) {
        super(message);
    }

    public AppServiceException(final Throwable cause) {
        super(cause);
    }

    public AppServiceException(String code, String message) {
        this(message);
        this.code = code;
    }
}

3)项目结构及Resource Bundle的创建

在resource的目录下创建resource bundle。

image-20201020145119809

项目结构:

image-20201020144505856

4)application.yml配置文件

logging:
  file:
    name: slf4j-test
    path: ./logs
    max-size: 10MB
  level:
    root: info
  config: classpath:logback-gnete.xml

spring:
  messages:
    basename: messages_zh

5)业务层接口及实现类

  • interface
package com.example.demo.interfaces;


import com.example.demo.exceptions.AppServiceException;

public interface ExceptionService {

    void exceptionTest() throws AppServiceException;
    double GlobalExceptionTest(Integer num);
}
  • AbstractService
package com.example.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;


@Service
public class AbstractService {

    // 注入messageSource
    @Autowired
    private MessageSource messageSource;

    public String getMessage(String code, String defaultMsg) {
        return this.messageSource.getMessage(code, null, defaultMsg, LocaleContextHolder.getLocale());
    }

    public String getMessage(String code) {
        return this.getMessage(code, "");
    }
}
  • serviceImp
package com.example.demo.service;

import com.example.demo.enums.ErrorCode;
import com.example.demo.exceptions.AppServiceException;
import com.example.demo.interfaces.ExceptionService;
import org.springframework.stereotype.Service;

@Service
public class ExceptionServiceImp extends AbstractService implements ExceptionService {


    @Override
    public void exceptionTest() throws AppServiceException {
        throw new AppServiceException(ErrorCode.HELLO_EXCEPTION, this.getMessage(ErrorCode.HELLO_EXCEPTION));
    }

    @Override
    public double GlobalExceptionTest(Integer num){
        return (double) num / 0;
    }
}

6)返回的结果类

package com.example.demo.pojo;

import java.io.Serializable;

public class ReponseResult<T> implements Serializable {
    private static final long serialVersionUID = 9191892693219217387L;
    private static final String RESP_CODE_SUCCESS = "00000000";
    private String code;
    private boolean success;
    private String message;
    private T data;

    public ReponseResult() {
    }

    public String getCode() {
        return this.code;
    }

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

    public String getMessage() {
        return this.message;
    }

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

    public T getData() {
        return this.data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public boolean isSuccess() {
        return this.success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public static <T> ReponseResult<T> success(T data) {
        ReponseResult<T> result = new ReponseResult();
        result.setCode("00000000");
        result.setMessage("成功");
        result.setSuccess(true);
        result.setData(data);
        return result;
    }

    public static <T> ReponseResult<T> fail(String code, String message, T data) {
        ReponseResult<T> result = new ReponseResult();
        result.setCode(code);
        result.setData(data);
        result.setMessage(message);
        result.setSuccess(false);
        return result;
    }

    public static <T> ReponseResult<T> fail(String code, String message) {
        ReponseResult<T> result = new ReponseResult();
        result.setCode(code);
        result.setMessage(message);
        result.setSuccess(false);
        result.setData((T) null);
        return result;
    }
}

7)全局异常处理handler

package com.example.demo.handler;


import com.example.demo.enums.ErrorCode;
import com.example.demo.exceptions.AppServiceException;
import com.example.demo.pojo.ReponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = AppServiceException.class)
    @ResponseBody
    public ReponseResult appServiceExceptionHandler(AppServiceException e){
        log.error("发生业务异常!原因是:{}",e.getMessage());
        return ReponseResult.fail(e.getCode(),e.getMessage());
    }

    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public  ReponseResult appServiceRuntimeException(RuntimeException e){
        log.error("发生运行时业务异常!原因是:{}",e.getMessage());
        return ReponseResult.fail(String.valueOf(400),e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public  ReponseResult noPermissionException(NullPointerException e){
        log.error("空指针异常!原因是:{}",e.getMessage());
        return ReponseResult.fail("90000003","数据不存在");
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public  ReponseResult commonExceptionHandler(Exception e){
        log.error("通用异常!原因是:{}",e.getMessage());
        return ReponseResult.fail(ErrorCode.SERVICE_EXCEPTION,e.getMessage());
    }
}
  • @ControllerAdvice 捕获 Controller 层抛出的异常,如果添加 @ResponseBody 返回信息则为JSON 格式。
  • @RestControllerAdvice 相当于 @ControllerAdvice@ResponseBody 的结合体。
  • @ExceptionHandler 统一处理一种类的异常,减少代码重复率,降低复杂度。

8)控制层

package com.example.demo.controller;

import com.example.demo.exceptions.AppServiceException;
import com.example.demo.interfaces.ExceptionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@Slf4j
public class TestController {

    @Autowired
    ExceptionService exceptionService;

    @GetMapping("/exceptionTest")
    public String test2() throws AppServiceException {
        log.debug("自定义异常处理");
        exceptionService.exceptionTest();
        return "ok";
    }

    @GetMapping("/GlobalExceptionTest")
    public double test2(Integer num) throws AppServiceException {
        log.debug("全局异常处理");
        return exceptionService.GlobalExceptionTest(num);
    }
}

9)异常处理结果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书生伯言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值