框架抛出来的或者一些第三方的组件抛出来的异常。我们根本不知道它所对应的错误代码的信息,所以我们也没有办法给用户返回具体的错误代码和错误信息。
我们先在Map中定义有一些不可预知的异常,定义错误代码和错误信息。如果我们在map中找到了这个错误代码,我们可以给用户返回,如果我们没有找到。就返回统一的99999异常
这种异常我们自定义的错误代码。例如返回操作失败,请与管理员联系这种。
对于不可预知的异常我们这么去处理。

首先模拟一下不可预知的异常。添加的方法,我们body里面不传json数据就调用后端方法

这个时候返回了400错误信息,这不是我们统一的响应格式信息。

这才是我们统一的响应信息

要么把这类异常返回为99999。要么就把这些异常定义一个具体的代码

首先在项目里面我们想把这类异常捕获到。在异常捕获类里面,这里@ExceptionHandler来捕获Exception.class这个类型的异常。
但是这里我们获取不到异常的代码

在这里加一个断点,我们看下异常的类型是什么

断点进来。把这个捕获的异常信息复制出去。


org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.xuecheng.framework.domain.cms.response.CmsPageResult com.xuecheng.manage_cms.controller.CmsPageController.add(com.xuecheng.framework.domain.cms.CmsPage)

异常意思是请求的body 没有数据

针对这类异常我们统一返回99999。就是CommCode这个枚举里面的Server_error

例如这里我们返回99999

  1.  
  1. @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult exception(Exception exception){
    //记录日志
    LOGGER.error("catch exception:{}",exception.getMessage());
    return new ResponseResult(CommonCode.SERVER_ERROR);
    }
  1.  

这样最终统一返回的数据如下

Map中定义

有些不可预知的异常是可以定义错误代码的

我们可以对HttpMessageNotReadableException这个类型定义错误代码。

在CommonCode定义非法参数的这个枚举

  1. INVALID_PARAM(false,,"非法参数"),

ImmutableMap 是谷歌的工具包下的类型,这个map的数据一旦放进去是不可更改的。也就是只读的

前面的表示异常类型,异常都是会继承Throwable。后面是异常代码

再定义builder对象,builder对象是用来构建ImmutableMap的。注意修饰符是protected

那么怎么去构建呢?放在静态代码块里面。现在这个数据还在这个builder里面 ,一旦builder把数据构建到Map里面。这个map的数据将不能更改。

使用builder.build方法构建Map

  1. package com.xuecheng.framework.exception;
  2.  
  3. import com.google.common.collect.ImmutableMap;
  4. import com.xuecheng.framework.model.response.CommonCode;
  5. import com.xuecheng.framework.model.response.ResponseResult;
  6. import com.xuecheng.framework.model.response.ResultCode;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.http.converter.HttpMessageNotReadableException;
  10. import org.springframework.web.bind.annotation.ControllerAdvice;
  11. import org.springframework.web.bind.annotation.ExceptionHandler;
  12. import org.springframework.web.bind.annotation.ResponseBody;
  13.  
  14. @ControllerAdvice
  15. public class ExceptionCatch {
  16. private static final Logger LOGGER= LoggerFactory.getLogger(ExceptionCatch.class);
  17. //定义Map 配置异常类型所对应的错误代码
  18. private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
  19. //定义map的builder对象,去构建ImmutableMap
  20. protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder=ImmutableMap.builder();
  21. //捕获CustomException此类异常
  22. @ExceptionHandler(CustomException.class)
  23. @ResponseBody
  24. public ResponseResult customException(CustomException customException){
  25. //获取异常信息,日志记录异常
  26. LOGGER.error("catch exception:{}",customException.getMessage());
  27. ResultCode resultCode=customException.getResultCode();
  28. return new ResponseResult(resultCode);
  29. }
  30. @ExceptionHandler(Exception.class)
  31. @ResponseBody
  32. public ResponseResult exception(Exception exception){
  33. //记录日志
  34. LOGGER.error("catch exception:{}",exception.getMessage());
  35. if (EXCEPTIONS==null){
  36. builder.build();//EXCEPTIONS构建成功
  37. }
  38. //从EXCEPTIONS对象最后中获取大当前的这个传递过来的exception的错误代码,
  39. ResultCode resultCode=EXCEPTIONS.get(exception.getClass());
  40. if(resultCode!=null){
  41. return new ResponseResult(resultCode);//最终返回这个错误代码。
  42. }else{
  43. return new ResponseResult(CommonCode.SERVER_ERROR);
  44. }
  45. }
  46.  
  47. static {
  48. //把异常的类和错误代码加入到builder对象里面。
  49. builder.put(HttpMessageNotReadableException.class,CommonCode.INVALID_PARAM);
  50. }
  51. }

测试

http://localhost:31001/cms/page/add

在这里加一个断点

空指针异常

这里应该用EXCEPTIONS来接收build构建的map对象。

  1. if (EXCEPTIONS==null){
    EXCEPTIONS=builder.build();//EXCEPTIONS构建成功
    }

再次测试

找到了错误代码并返回。

把这个请求改成get再去请求数据。返回的错误代码是 99999 因为这个错误没有加入到我们错误Map集合中。

以上不可预知异常处理就做完了。

完整代码

  1. package com.xuecheng.framework.exception;
  2.  
  3. import com.google.common.collect.ImmutableMap;
  4. import com.xuecheng.framework.model.response.CommonCode;
  5. import com.xuecheng.framework.model.response.ResponseResult;
  6. import com.xuecheng.framework.model.response.ResultCode;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.http.converter.HttpMessageNotReadableException;
  10. import org.springframework.web.bind.annotation.ControllerAdvice;
  11. import org.springframework.web.bind.annotation.ExceptionHandler;
  12. import org.springframework.web.bind.annotation.ResponseBody;
  13.  
  14. @ControllerAdvice
  15. public class ExceptionCatch {
  16. private static final Logger LOGGER= LoggerFactory.getLogger(ExceptionCatch.class);
  17. //定义Map 配置异常类型所对应的错误代码
  18. private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
  19. //定义map的builder对象,去构建ImmutableMap
  20. protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder=ImmutableMap.builder();
  21. //捕获CustomException此类异常
  22. @ExceptionHandler(CustomException.class)
  23. @ResponseBody
  24. public ResponseResult customException(CustomException customException){
  25. //获取异常信息,日志记录异常
  26. LOGGER.error("catch exception:{}",customException.getMessage());
  27. ResultCode resultCode=customException.getResultCode();
  28. return new ResponseResult(resultCode);
  29. }
  30. @ExceptionHandler(Exception.class)
  31. @ResponseBody
  32. public ResponseResult exception(Exception exception){
  33. //记录日志
  34. LOGGER.error("catch exception:{}",exception.getMessage());
  35. if (EXCEPTIONS==null){
  36. EXCEPTIONS=builder.build();//EXCEPTIONS构建成功
  37. }
  38. //从EXCEPTIONS对象最后中获取大当前的这个传递过来的exception的错误代码,
  39. ResultCode resultCode=EXCEPTIONS.get(exception.getClass());
  40. if(resultCode!=null){
  41. return new ResponseResult(resultCode);//最终返回这个错误代码。
  42. }else{
  43. return new ResponseResult(CommonCode.SERVER_ERROR);
  44. }
  45. }
  46.  
  47. static {
  48. //把异常的类和错误代码加入到builder对象里面。
  49. builder.put(HttpMessageNotReadableException.class,CommonCode.INVALID_PARAM);
  50. }
  51. }

ExceptionCatch

阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_18-异常处理-不可预知异常处理的更多相关文章

  1. 微服务项目开发学成在线_day03 CMS页面管理开发

    springboot引入mangodb依赖坐标:在spring-boot集成条件下,使用mongodb的DAO层开发. swagger查看接口文档,请求地址:http://localhost:3100 ...

  2. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_24-页面预览-页面预览测试

    通过nginx转发到预览的地址 重启nginx 添加页面预览按钮 调整下列表的列的宽度

  3. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_23-页面预览-页面预览开发

    1.用户进入cms前端,点击“页面预览”在浏览器请求cms页面预览链接. 2.cms根据页面id查询DataUrl并远程请求DataUrl获取数据模型. 3.cms根据页面id查询页面模板内容 4.c ...

  4. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_16-页面静态化-模板管理-模板制作

    这是轮播图的原始文件 运行门户需要把 nginx启动起来 单独运行轮播图.把里面的css的引用都加上网址的url 这就是单独访问到的轮播图的效果 轮播图模板的地址: 阶段5 3.微服务项目[学成在线] ...

  5. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_16-CMS前端工程创建-导入系统管理前端工程

    提供了基于脚手架封装好的前端工程 H:\BaiDu\黑马传智JavaEE57期 2019最新基础+就业+在职加薪\阶段5 3.微服务项目[学成在线]·\day02 CMS前端开发\资料\xc-ui-p ...

  6. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_03-用户认证技术方案-Oauth2协议

    2.2 Oauth2认证 2.2.1 Oauth2认证流程 第三方认证技术方案最主要是解决认证协议的通用标准 问题,因为要实现 跨系统认证,各系统之间要遵循一定的 接口协议. OAUTH协议为用户资源 ...

  7. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_01-用户认证需求分析

    1.1 用户认证与授权 截至目前,项目已经完成了在线学习功能,用户通过在线学习页面点播视频进行学习.如何去记录学生的学习过程 呢?要想掌握学生的学习情况就需要知道用户的身份信息,记录哪个用户在什么时间 ...

  8. 微服务项目开发学成在线_day02 CMS前端开发

    1 Vue.js与Webpack研究 开发版的浏览器:https://www.google.cn/intl/zh-CN/chrome/dev/ 前端的开发框架:微服务项目开发学成在线_Vue.js与W ...

  9. 阶段5 3.微服务项目【学成在线】_day09 课程预览 Eureka Feign_05-Feign远程调用-客户端负载均衡介绍

    2 Feign远程调用 在前后端分离架构中,服务层被拆分成了很多的微服务,服务与服务之间难免发生交互,比如:课程发布需要调用 CMS服务生成课程静态化页面,本节研究微服务远程调用所使用的技术. 下图是 ...

随机推荐

  1. Introduction of Machine Learning

    李宏毅主页 台湾大学语音处理实验室 人工智慧.机器学习与深度学习间有什么区别? 人工智能——目标 机器学习——手段 深度学习——机器学习的一种方法 人类设定好的天生本能 Machine Learnin ...

  2. css一个元素垂直居中的6种方法

    方法一: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  3. 搭建一个jumpserver跳板机

    1,部署jumpserver 建立阿里云公网源yum仓库 清除缓存重新建立缓存 ip后面直接回车,下面输入y 地址端口账户密码直接回车 ,询问跳过输入y,是否继续输入y 用户名回车,输入自己要设置的密 ...

  4. PAT Basic 1070 结绳 (25 分)

    给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下图所示套接在一起.这样得到的绳子又被当成是另一段绳子,可以再次对折去跟另一段绳子串连.每次串连后,原来两段绳子的长度 ...

  5. Pandas-Numpy-Scipy-Matplotlib

    Ref:Using iloc, loc, & ix to select rows and columns in Pandas DataFrames 单纯的方括号只有两个用途:基于列的label ...

  6. golang 2 ways to delete an element from a slice

    2 ways to delete an element from a slice yourbasic.org/golang Fast version (changes order) a := []st ...

  7. .net FileUpload上传图片 图片转换二进制,以及保存显示

    protected void Button1_Click(object sender, EventArgs e) { Stream stream = FileUpload1.PostedFile.In ...

  8. adb常用命令及简介

    平时开发android应用 的时候,我们都会用到包含在Android SDK中一系列的工具,或许我们通过Eclipse去调用,又或许,我们自己通过打开终端进行手动输入并且执行,下面我们来一起学习下这些 ...

  9. SIGAI机器学习第十集 线性判别分析

    讲授LDA基本思想,寻找最佳投影矩阵,PCA与LDA的比较,LDA的实际应用 前边讲的数据降维算法PCA.流行学习都是无监督学习,计算过程中没有利用样本的标签值.对于分类问题,我们要达到的目标是提取或 ...

  10. Guardian of Decency POJ - 2771 【二分匹配,最大独立集】

    Problem DescriptionFrank N. Stein is a very conservative high-school teacher. He wants to take some ...