SpringBoot2.0系列教程(五)Springboot框架添加全局异常处理

Stella981
• 阅读 139

Hello大家好,本章我们添加全局异常处理。另求各路大神指点,感谢

一:为什么需要定义全局异常

在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,所以我们需要对异常进行捕获,然后给予相应的处理,来减少程序异常对用户体验的影响

二:添加业务类异常

在前面说过的ret文件夹下创建ServiceException

package com.example.demo.core.ret;

import java.io.Serializable;

/**
 * @Description: 业务类异常
 * @author 张瑶
 * @date 2018/4/20 14:30
 * 
 */
public class ServiceException extends RuntimeException implements Serializable{

   private static final long serialVersionUID = 1213855733833039552L;

   public ServiceException() {
   }

   public ServiceException(String message) {
      super(message);
   }

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

三:添加异常处理配置

打开上篇文章创建的WebConfigurer,添加如下方法

@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
    exceptionResolvers.add(getHandlerExceptionResolver());
}

/**
 * 创建异常处理
 * @return
 */
private HandlerExceptionResolver getHandlerExceptionResolver(){
    HandlerExceptionResolver handlerExceptionResolver = new HandlerExceptionResolver(){
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
                                             Object handler, Exception e) {
            RetResult<Object> result = getResuleByHeandleException(request, handler, e);
            responseResult(response, result);
            return new ModelAndView();
        }
    };
    return handlerExceptionResolver;
}

/**
 * 根据异常类型确定返回数据
 * @param request
 * @param handler
 * @param e
 * @return
 */
private RetResult<Object> getResuleByHeandleException(HttpServletRequest request, Object handler, Exception e){
    RetResult<Object> result = new RetResult<>();
    if (e instanceof ServiceException) {
        result.setCode(RetCode.FAIL).setMsg(e.getMessage()).setData(null);
        return result;
    }
    if (e instanceof NoHandlerFoundException) {
        result.setCode(RetCode.NOT_FOUND).setMsg("接口 [" + request.getRequestURI() + "] 不存在");
        return result;
    }
    result.setCode(RetCode.INTERNAL_SERVER_ERROR).setMsg("接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员");
    String message;
    if (handler instanceof HandlerMethod) {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s", request.getRequestURI(),
                handlerMethod.getBean().getClass().getName(), handlerMethod.getMethod() .getName(), e.getMessage());
    } else {
        message = e.getMessage();
    }
    LOGGER.error(message, e);
    return result;
}

/**
 * @Title: responseResult
 * @Description: 响应结果
 * @param response
 * @param result
 * @Reutrn void
 */
private void responseResult(HttpServletResponse response, RetResult<Object> result) {
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type", "application/json;charset=UTF-8");
    response.setStatus(200);
    try {
        response.getWriter().write(JSON.toJSONString(result,SerializerFeature.WriteMapNullValue));
    } catch (IOException ex) {
        LOGGER.error(ex.getMessage());
    }
}

四:添加配置文件

Spring Boot 中, 当用户访问了一个不存在的链接时, Spring 默认会将页面重定向到 **/error** 上, 而不会抛出异常.

既然如此, 那我们就告诉 Spring Boot, 当出现 404 错误时, 抛出一个异常即可. 

在 application.properties 中添加两个配置: 

spring.mvc.throw-exception-if-no-handler-found=true 

spring.resources.add-mappings=false 

上面的配置中, 第一个 spring.mvc.throw-exception-if-no-handler-found 告诉 SpringBoot 当出现 404 错误时, 直接抛出异常. 第二个 spring.resources.add-mappings 告诉 SpringBoot 不要为我们工程中的资源文件建立映射.

五:创建测试接口

package com.example.demo.service.impl;

import com.example.demo.core.ret.ServiceException;
import com.example.demo.dao.UserInfoMapper;
import com.example.demo.model.UserInfo;
import com.example.demo.service.UserInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 张瑶
 * @Description:
 * @time 2018/4/18 11:56
 */
@Service
public class UserInfoServiceImpl implements UserInfoService{

    @Resource
    private UserInfoMapper userInfoMapper;

    @Override
    public UserInfo selectById(Integer id){
        UserInfo userInfo = userInfoMapper.selectById(id);
        if(userInfo == null){
            throw new ServiceException("暂无该用户");
        }
        return userInfo;
    }
}

UserInfoController.java

package com.example.demo.controller;

import com.example.demo.core.ret.RetResponse;
import com.example.demo.core.ret.RetResult;
import com.example.demo.core.ret.ServiceException;
import com.example.demo.model.UserInfo;
import com.example.demo.service.UserInfoService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 张瑶
 * @Description:
 * @time 2018/4/18 11:39
 */
@RestController
@RequestMapping("userInfo")
public class UserInfoController {

    @Resource
    private UserInfoService userInfoService;

    @PostMapping("/hello")
    public String hello(){
        return "hello SpringBoot";
    }

    @PostMapping("/selectById")
    public RetResult<UserInfo> selectById(Integer id){
        UserInfo userInfo = userInfoService.selectById(id);
        return RetResponse.makeOKRsp(userInfo);
    }

    @PostMapping("/testException")
    public RetResult<UserInfo> testException(Integer id){
        List a = null;
        a.size();
        UserInfo userInfo = userInfoService.selectById(id);
        return RetResponse.makeOKRsp(userInfo);
    }


}

六:接口测试

访问192.168.1.104:8080/userInfo/selectById参数 id:3

{
    "code": 400,
    "data": null,
    "msg": "暂无该用户"
}

访问192.168.1.104:8080/userInfo/testException

{
    "code": 500,
    "data": null,
    "msg": "接口 [/userInfo/testException] 内部错误,请联系管理员"
}

项目地址

码云地址: https://gitee.com/beany/mySpringBoot

GitHub地址: https://github.com/MyBeany/mySpringBoot

写文章不易,如对您有帮助,请帮忙点下starSpringBoot2.0系列教程(五)Springboot框架添加全局异常处理

结尾

springboot添加全局异常处理已完成,后续功能接下来陆续更新。另求各路大神指点,感谢大家。

点赞
收藏
评论区
推荐文章
Souleigh ✨ Souleigh ✨
1年前
前端 - 常见的异常捕获方法
前端异常捕获在ES3之前js代码执行的过程中,一旦出现错误,整个js代码都会停止执行,这样就显的代码非常的不健壮。从ES3开始,js也提供了类似的异常处理机制,从而让js代码变的更健壮,程序执行的过程中出现了异常,也可以让程序具有了一部分的异常恢复能力。js异常的特点是,出现不会导致JS引擎崩溃,最多只会终止当前执行的任务。回归正题,我们该如何在程序异常发生
艾木酱 艾木酱
1个月前
快速入门|使用MemFire Cloud构建React Native应用程序
> MemFire Cloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
Spring Cloud Gateway 全局通用异常处理
为什么需要全局异常处理 ----------- 在传统 Spring Boot 应用中, 我们 @ControllerAdvice 来处理全局的异常,进行统一包装返回 // 摘至 spring cloud alibaba console 模块处理 @ControllerAdvice public class Consol
Wesley13 Wesley13
1年前
03.Android崩溃Crash库之ExceptionHandler分析
#### 目录总结 * 00.异常处理几个常用api * 01.UncaughtExceptionHandler * 02.Java线程处理异常分析 * 03.Android中线程处理异常分析 * 04.为何使用setDefaultUncaughtExceptionHandler ### 前沿 * 上一篇整体介绍了crash崩溃
Wesley13 Wesley13
1年前
初探 Objective
> 作者: Cyandev, iOS 和 MacOS 开发者,目前就职于字节跳动 ### 0x00 前言 异常处理是许多高级语言都具有的特性,它可以直接中断当前函数并将控制权转交给能够处理异常的函数。不同语言在异常处理的实现上各不相同,本文主要来分析一下 Objective-C 和 C++ 这两个语言。 为什么要把 Objective-C 和
Stella981 Stella981
1年前
Android全局异常捕获,不退出应用,让应用正常运行下去!
Android全局异常捕获,不退出应用,让应用正常运行下去! 当App发现异常后,如果程序没有处理,将交给虚拟机进行处理,通常会弹出一个对话框,然后退出应用。但大多数的异常可能对后续流程影响不大,比如分享功能出现。 一个问题,真的有必要关闭整个应用吗?屏蔽这个功能,对整体来说不会有太大的影响。或者某个页面的数据出现了逻辑错误,大多数关闭当
Wesley13 Wesley13
1年前
PostgreSQL疑难问题分析步骤
运维管理postgresql 时难免不会遇到一些疑难问题,遇到这里问题时怎么处理呢。 一、分析是整库异常还是个别进程异常 ================= 二、首先收集信息 ======== 确认好异常类别后,可以进行收集相应的信息了 整库异常 ---- 1.    检查server状态 执行pg\_ctl status \[-D datad
Stella981 Stella981
1年前
SpringBoot过滤器中的异常处理
在昨天的文章我跟大家分享了SpringBoot中异常的处理中,我说了一个需要注意的点,就是过滤器中抛出的异常无法被异常处理类捕获,然后这个朋友就问应该如何处理。 其实处理这种问题的处理方式有好几种,那么我就简单分享一下我近期一个项目中的处理方式。 Filter中的异常处理思路 -------------- 首先我们要明白,在过滤器中我们一般是不会写很长
Stella981 Stella981
1年前
SpringBoot2.0 基础案例(03):配置系统全局异常映射处理
本文源码 GitHub:知了一笑 https://github.com/cicadasmile/spring-boot-base 一、异常分类 ====== 这里的异常分类从系统处理异常的角度看,主要分类两类:业务异常和系统异常。 1、业务异常 ------ 业务异常主要是一些可预见性异常,处理业务异常,用来提示用户
Stella981 Stella981
1年前
SpringBoot2 全局异常处理
**参考这篇文章里面的几种异常形式:** > 全局异常处理是个比较重要的功能,一般在项目里都会用到。  > 大概把一次请求分成三个阶段,来分别进行全局的异常处理。  > 一:在进入Controller之前,譬如请求一个不存在的地址,404错误。  > 二:在执行@RequestMapping时,进入逻辑处理阶段前。譬如传的参数类型错误。 
helloworld_28799839 helloworld_28799839
2个月前
常用知识整理
# Javascript ## 判断对象是否为空 ```js Object.keys(myObject).length === 0 ``` ## 经常使用的三元运算 > 我们经常遇到处理表格列状态字段如 `status` 的时候可以用到 ``` vue