springboot 全局异常

版权声明:版权所有,如需转载,请注明出处 https://blog.csdn.net/houdezaiwu1/article/details/89846632

1. 自定义异常

在应用开发过程中,除系统自身的异常外,不同业务场景中用到的异常也不一样,为了与标题 轻松搞定全局异常 更加的贴切,定义个自己的异常,看看如何捕获…

package com.example.exception;

/**
 * Created by Administrator on 2019/5/5.
 * 1  自定义异常
 */
public class GlobalException extends RuntimeException {
    private static final long serialVersionUID = 4564124491192825748L;
    private int code;

    public GlobalException( int code,String message) {
        super(message);
        this.code = code;
    }

    public GlobalException() {
    }
    public int getCode() {
        return code;
    }

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

2 定义异常模板

这样返回的数据格式更加统一

package com.example.exception;

/**
 * Created by Administrator on 2019/5/5.
 * 2. 异常信息模板   定义返回的异常信息的格式,这样异常信息风格更为统一
 */
public class ErrorExceptionEntity {
    private int code;
    private String message;

    public ErrorExceptionEntity() {
    }

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

    public int getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

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

3 异常处理

这是最关键的,将不同的异常分发给不同的处理逻辑

  • @ControllerAdvice 捕获 Controller 层抛出的异常,如果添加 @ResponseBody 返回信息则为JSON 格式。
  • @RestControllerAdvice 相当于 @ControllerAdvice 与 @ResponseBody 的结合体。
  • @ExceptionHandler 统一处理一种类的异常,减少代码重复率,降低复杂度。
package com.example.handler;

import com.example.exception.ErrorExceptionEntity;
import com.example.exception.GlobalException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by Administrator on 2019/5/5.
 * 全局异常处理
 */
@RestControllerAdvice
public class GlobalExceptionHander extends ResponseEntityExceptionHandler {

    @ExceptionHandler(GlobalException.class)
    public ErrorExceptionEntity globalExceptonHandler(HttpServletRequest request, final Exception e, HttpServletResponse response){
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        RuntimeException exception = (RuntimeException) e;
        return new ErrorExceptionEntity(400, exception.getMessage());
    }
    /**
     * 捕获  RuntimeException 异常
     * TODO  如果你觉得在一个 exceptionHandler 通过  if (e instanceof xxxException) 太麻烦
     * TODO  那么你还可以自己写多个不同的 exceptionHandler 处理不同异常
     *
     * @param request  request
     * @param e        exception
     * @param response response
     * @return 响应结果
     */
    @ExceptionHandler(RuntimeException.class)
    public ErrorExceptionEntity runtimeExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        RuntimeException exception = (RuntimeException) e;
        return new ErrorExceptionEntity(400, exception.getMessage());
    }
    /**
     * 通用的接口映射异常处理方
     */
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
                                                             HttpStatus status, WebRequest request) {
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            return new ResponseEntity<>(new ErrorExceptionEntity(status.value(), exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
        }
        if (ex instanceof MethodArgumentTypeMismatchException) {
            MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
            logger.error("参数转换失败,方法:" + exception.getParameter().getMethod().getName() + ",参数:" + exception.getName()
                    + ",信息:" + exception.getLocalizedMessage());
            return new ResponseEntity<>(new ErrorExceptionEntity(status.value(), "参数转换失败"), status);
        }
        return new ResponseEntity<>(new ErrorExceptionEntity(status.value(), "参数转换失败"), status);
    }
}

4 控制层

/**
     * 自定义异常测试
     * @param num
     * @return
     */
    @GetMapping("/testGlobalException")
    @ApiOperation(value="自定义异常测试",notes = "")
    @ResponseBody
    public String testGlobalException(Integer num){
        // TODO 演示需要,实际上参数是否为空通过 @RequestParam(required = true)  就可以控制
        if (num == null) {
            throw new GlobalException(400, "num不能为空");
        }
        int i = 10 / num;
        return "result:" + i;
    }

swagger 测试省略了。。。

参考文档: https://blog.battcn.com/2018/06/01/springboot/v2-other-exception/

猜你喜欢

转载自blog.csdn.net/houdezaiwu1/article/details/89846632