spring下全局异常处理

经常要处理一些controller报出来的异常 ,以免报错到前端页面形成不好的用户体验。

一个个处理很繁琐,容易漏掉,而且很不优雅。最近发现可以用全局异常来处理。非常的方便,而且有个好处就是返回的样式很统一。

在异常处理中主要运用了spring的注解@ControllerAdvice

效果是这样的滴。


下面上代码

全局异常处理类


package com.pobo.liang.ws.exceptionHandler;

import com.pobo.liang.ws.model.Result;
import com.pobo.liang.ws.utils.ExceptionUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ValidationException;

/**
 * 异常处理
 */
@RestController
@CrossOrigin
@ControllerAdvice
class GlobalExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private HttpServletRequest req;
    private HttpRequestMethodNotSupportedException e;

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    Object exception(HttpServletRequest req, Exception e) {
        e.printStackTrace();
        logger.error("系统错误: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(500, "系统错误");
    }

    @ExceptionHandler(value = IllegalArgumentException.class)
    @ResponseBody
    Object exception(HttpServletRequest req, IllegalArgumentException e) {
        e.printStackTrace();
        logger.error("Assert错误: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(1000, e.getMessage());
    }

    @ExceptionHandler(value = NoHandlerFoundException.class)
    @ResponseBody
    Object noHandlerFoundException(HttpServletRequest req, NoHandlerFoundException e) {
        logger.error("找不到请求路径: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(404, e.getLocalizedMessage());
    }

    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    Object httpRequestMethodNotSupportedException(HttpServletRequest req, HttpRequestMethodNotSupportedException e) {
        logger.error("请求method不支持: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }

    @ExceptionHandler(value = TypeMismatchException.class)
    @ResponseBody
    Object TypeMismatchException(HttpServletRequest req, TypeMismatchException e) {
        logger.error("缺少请求参数: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }

    @ExceptionHandler(value = ValidationException.class)
    @ResponseBody
    Object ValidationException(HttpServletRequest req, ValidationException e) {
        logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }


    @ExceptionHandler(value = MissingPathVariableException.class)
    @ResponseBody
    Object MissingPathVariableException(HttpServletRequest req, MissingPathVariableException e) {
        logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    Object MethodArgumentNotValidException(HttpServletRequest req, MethodArgumentNotValidException e) {
        logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }

    @ExceptionHandler(value = UnsatisfiedServletRequestParameterException.class)
    @ResponseBody
    Object UnsatisfiedServletRequestParameterException(HttpServletRequest req, UnsatisfiedServletRequestParameterException e) {
        logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }

    @ExceptionHandler(value = ServletRequestBindingException.class)
    @ResponseBody
    Object ServletRequestBindingException(HttpServletRequest req, ServletRequestBindingException e) {
        logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }

    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseBody
    Object MissingServletRequestParameterException(HttpServletRequest req, MissingServletRequestParameterException e) {
        logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(400, e.getLocalizedMessage());
    }


    @ExceptionHandler(value = IncorrectCredentialsException.class)
    @ResponseBody
    Object incorrectCredentialsException(HttpServletRequest req, IncorrectCredentialsException e) {
        logger.error("用户名或密码错误: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(405, "用户名或密码错误");
    }

    @ExceptionHandler(value = LockedAccountException.class)
    @ResponseBody
    Object lockedAccountException(HttpServletRequest req, LockedAccountException e) {
        logger.error("登录失败,该用户已被冻结: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(405, "登录失败,该用户已被冻结");
    }

    @ExceptionHandler(value = AuthenticationException.class)
    @ResponseBody
    Object authenticationException(HttpServletRequest req, AuthenticationException e) {
        logger.error("用户名或密码错误: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(405, "用户名或密码错误");
    }


    @ExceptionHandler(value = ExpiredCredentialsException.class)
    @ResponseBody
    Object expiredCredentialsException(HttpServletRequest req, ExpiredCredentialsException e) {
        logger.error("token已过期: [{}]", ExceptionUtil.getExceptionStackTrace(e));
        return Result.ofFailure(405, "token已过期");
    }

}

返回类型的实体类:

package com.pobo.liang.ws.model;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.Serializable;

public class Result<T> implements Serializable {
    private int errcode;
    private String errmsg;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private T body;

    public static Result ofSuccess() {
        return new Result(0, "success");
    }

    public static Result ofSuccess(String msg) {
        return new Result(0, msg);
    }

    public static Result ofFailure(int errcode, String errmsg) {
        return new Result(errcode, errmsg);
    }

    public Result() {
    }

    public Result(int errcode, String errmsg) {
        this.errcode = errcode;
        this.errmsg = errmsg;
    }

    public Result(int errcode, String errmsg, T body) {
        this.errcode = errcode;
        this.errmsg = errmsg;
        this.body = body;
    }

    public int getErrcode() {
        return errcode;
    }

    public Result setErrcode(int errcode) {
        this.errcode = errcode;
        return this;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public Result setErrmsg(String errmsg) {
        this.errmsg = errmsg;
        return this;
    }

    public Object getBody() {
        return body;
    }

    public Result setBody(T body) {
        this.body = body;
        return this;
    }
}
 

异常工具类:

package com.pobo.liang.ws.utils;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class ExceptionUtil {
    public static String getExceptionStackTrace(Throwable throwable) {
        if (throwable == null) {
            return null;
        }

        try (StringWriter sw = new StringWriter(); PrintWriter printWriter = new PrintWriter(sw);) {
            throwable.printStackTrace(printWriter);
            printWriter.flush();
            sw.flush();
            return sw.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值