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("缺少请求参数: [{}]",e.getLocalizedMessage());
    }

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


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

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

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

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

    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseBody
    Object MissingServletRequestParameterException(HttpServletRequest req,MissingServletRequestParameterException e) {
        logger.error("参数验证失败: [{}]",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("登录失败,该用户已被冻结: [{}]","登录失败,该用户已被冻结");
    }

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


    @ExceptionHandler(value = ExpiredCredentialsException.class)
    @ResponseBody
    Object expiredCredentialsException(HttpServletRequest req,ExpiredCredentialsException e) {
        logger.error("token已过期: [{}]","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;
    }
}

原文地址:https://blog.csdn.net/qq_40006446

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


今天小编给大家分享的是Springboot下使用Redis管道(pipeline)进行批量操作的介绍,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起...
本篇文章和大家了解一下springBoot项目常用目录有哪些。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。springBoot项目常用目录springBoot项...
本篇文章和大家了解一下Springboot自带线程池怎么实现。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。一: ThreadPoolTaskExecuto1 ThreadP...
这篇文章主要介绍了SpringBoot读取yml文件有哪几种方式,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。Spring Boot读取yml文件的主要方式...
今天小编给大家分享的是SpringBoot配置Controller实现Web请求处理的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧...
本篇文章和大家了解一下SpringBoot实现PDF添加水印的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。简介PDF(Portable Document Form...
本篇文章和大家了解一下解决Springboot全局异常处理与AOP日志处理中@AfterThrowing失效问题的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有...
本篇文章和大家了解一下IDEA创建SpringBoot父子Module项目的实现方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录前言1. 软硬件环...
今天小编给大家分享的是springboot获取项目目录路径的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收...
本篇内容主要讲解“SpringBoot+Spring Security无法实现跨域如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面...
这篇文章主要介绍“vue怎么发送请求到springboot程序”,在日常操作中,相信很多人在vue怎么发送请求到springboot程序问题上存在疑惑,小编查阅了各式资料,整理...
本篇内容主要讲解“Springboot内置的工具类CollectionUtils如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家...
本文小编为大家详细介绍“SpringBoot上传文件大小受限如何解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringBoot上传文件大小受限如何解决”文章能帮...
本文小编为大家详细介绍“springboot拦截器如何创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“springboot拦截器如何创建”文章能帮助大家解决疑惑,下面...
本文小编为大家详细介绍“Hikari连接池使用SpringBoot配置JMX监控的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Hikari连接池使用SpringBoot配...
今天小编给大家分享一下SpringBoot如何使用Sa-Token实现权限认证的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大...
这篇文章主要介绍“SpringBoot如何集成SFTP客户端实现文件上传下载”,在日常操作中,相信很多人在SpringBoot如何集成SFTP客户端实现文件上传下...
本篇内容主要讲解“Springboot插件怎么开发”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Springboot插件怎
这篇文章主要介绍“Springboot怎么解决跨域请求问题”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇...
今天小编给大家分享一下如何在SpringBoot2中整合Filter的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文...