统一异常处理类的两种方式一种是前后分离,一种是一整套集合返回指定到指定的错误页面显示错误信息

1.由于前后分离,是统一返回JSON的格式

自定义Exception

  1. public class BussinessException extends RuntimeException {
  2.  
  3. private static final long serialVersionUID = 1L;
  4.  
  5. private int code;
  6. private String msg;
  7.  
  8. public BussinessException(String msg) {
  9. super();
  10. this.msg = msg;
  11. }
  12.  
  13. public BussinessException(int code, String msg) {
  14. super();
  15. this.code = code;
  16. this.msg = msg;
  17. }
  18.  
  19. public int getCode() {
  20. return code;
  21. }
  22.  
  23. public void setCode(int code) {
  24. this.code = code;
  25. }
  26.  
  27. public String getMsg() {
  28. return msg;
  29. }
  30.  
  31. public void setMsg(String msg) {
  32. this.msg = msg;
  33. }
  34.  
  35. }

  自定义统一异常处理类

  1. import java.io.IOException;
  2. import java.util.Date;
  3. import java.util.List;
  4.  
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7.  
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.core.annotation.Order;
  11. import org.springframework.http.MediaType;
  12. import org.springframework.validation.BindException;
  13. import org.springframework.validation.FieldError;
  14. import org.springframework.web.servlet.HandlerExceptionResolver;
  15. import org.springframework.web.servlet.ModelAndView;
  16.  
  17. import com.alibaba.fastjson.JSON;
  18. import com.bshf.recipe.exception.BussinessException;
  19. import com.bshf.recipe.vo.basic.ResultVO;
  20.  
  21. /**
  22. * 异常处理类
  23. *
  24. */
  25. @Order(-)
  26. public class ExceptionResolver implements HandlerExceptionResolver {
  27.  
  28. private static Logger logger = LoggerFactory.getLogger("exceptionLog");
  29.  
  30. @Override
  31. public ModelAndView resolveException(HttpServletRequest request,
  32. HttpServletResponse response, Object handler, Exception ex) {
  33. ResultVO result = new ResultVO();
  34. StringBuilder sb = new StringBuilder();
  35.  
  36. //处理异常
  37. if(ex instanceof BussinessException) {
  38. resolverBussinessException(ex, sb, result);
  39. } else if (ex instanceof BindException) {
  40. resolverBindException(ex, sb, result);
  41. } else {
  42. resolverOtherException(ex, sb, result);
  43. }
  44.  
  45. result.setCode();
  46. result.setResult(sb);
  47. result.setTime(new Date());
  48.  
  49. response.setContentType(MediaType.APPLICATION_JSON_VALUE);
  50. response.setCharacterEncoding("UTF-8");
  51. response.setHeader("Cache-Control", "no-cache, must-revalidate");
  52. try {
  53. response.getWriter().write(JSON.toJSONString(result));
  54. } catch (IOException e) {
  55. logger.error("与客户端通讯异常:" + e.getMessage(), e);
  56. e.printStackTrace();
  57. }
  58.  
  59. logger.debug("异常:" + ex.getMessage(), ex);
  60. ex.printStackTrace();
  61.  
  62. return new ModelAndView();
  63. }
  64.  
  65. /*
  66. * 处理业务层异常
  67. */
  68. private void resolverBussinessException(Exception ex, StringBuilder sb, ResultVO result) {
  69. BussinessException businessException = (BussinessException) ex;
  70. sb.append(businessException.getMsg());
  71. addResult(result, "业务异常");
  72. }
  73.  
  74. /*
  75. * 处理参数绑定异常
  76. */
  77. private void resolverBindException(Exception ex, StringBuilder sb, ResultVO result) {
  78. BindException be = (BindException) ex;
  79. List<FieldError> errorList = be.getBindingResult().getFieldErrors();
  80. for (FieldError error : errorList) {
  81. sb.append(error.getObjectName());
  82. sb.append("对象的");
  83. sb.append(error.getField());
  84. sb.append("字段");
  85. sb.append(error.getDefaultMessage());
  86. }
  87. addResult(result, "参数传递异常");
  88. }
  89.  
  90. /*
  91. * 处理其他异常
  92. */
  93. private void resolverOtherException(Exception ex, StringBuilder sb, ResultVO result) {
  94. sb.append(ex.getMessage());
  95. addResult(result, "其他异常");
  96. }
  97.  
  98. /*
  99. * 封装code和msg
  100. */
  101. private void addResult(ResultVO result, String msg) {
  102. result.setMsg(msg);
  103. }
  104.  
  105. }

配置文件

  1. <!-- 定义异常处理器 -->
  2. <bean id="exceptionResolver" class="com.execption.ExceptionResolver"/>

运行流程分析
当你请求项目中某个接口时,如果报异常了,则会首先进入到这个自定义异常处理类中,然后通过判断异常类型来具体给客户端返回不同的信息提示。若接口没报异常,则此类的方法是不会运行的。

问:为什么要加@Order(-1000)
答:因为Spring默认有三个异常拦截器,里面的order属性分别为0,1,2,会首先去这三个拦截器中找匹配的异常,若有匹配的,则不会执行我们自定义的异常处理器。@Order(-1000)的作用就是将顺序提到第一位,先加载我们的,有符合异常条件的,则不会继续走其他三个默认的。(我们这里一定会走,因为首先是order变成了-1000,其次是我们对自定义异常、BindException和其他做了捕获,所以一定不会执行Spring默认的)

问:为什么在最后添加了ex.printStackTrace();
答:一切为了调试方便,这样可以将异常信息打印到控制台,方便查看。

问:为什么要判断BindException?
答:一切为了调试方便。他会配合javax.validation.*中的注解一起用,比如客户端传入的参数加上了如下

  1. @NotNull(message = "id不能为空")
  2. private Integer id;
  3. @NotEmpty(message = "title不能为空或空字符串")
  4. private String title;

这时候我调用接口如果id和title都不传的话会进入我们的自定义异常处理类中去捕获,异常类型为BindException,会返回给客户端如下json:

  1. {
  2. "code": ,
  3. "msg": "参数传递异常",
  4. "result": "demoIO对象的title字段title不能为空或空字符串demoIO对象的id字段id不能为空",
  5. "time":
  6. }

这样就完成了统一异常处理。若没报异常则不会执行此方法,报异常则将异常信息返回给客户端方便调试。

  1. 2.后台管理同意处理返回到指定的错误页面方式
  1. /**
  2. *
  3. * 类名称:MyExceptionResolver.java
  4. * 类描述:
  5.  
  6. * @version 1.0
  7. */
  8. public class MyExceptionResolver implements HandlerExceptionResolver{
  9. protected Logger logger = Logger.getLogger(this.getClass());
  10. public ModelAndView resolveException(HttpServletRequest request,
  11. HttpServletResponse response, Object handler, Exception ex) {
  12. // TODO Auto-generated method stub
  13. System.out.println("==============异常开始=============");
  14. System.out.println("request.getRemoteAddr():"+request.getRemoteAddr());
  15. System.out.println("request.getMethod():"+request.getMethod());
  16. System.out.println("request.getQueryString():"+request.getQueryString());
  17. //logger.error("ex.getCause().getMessage():"+ex.getCause().getMessage());
  18. logger.error("request.getRequestURL():"+request.getRequestURL());
  19. //ex.printStackTrace();
  20. System.out.println("==============异常结束=============");
  21. ModelAndView mv = new ModelAndView("error");
  22. mv.addObject("exception", ex.toString().replaceAll("\n", "<br/>"));
  23.  
  24. return mv;
  25. }
  26.  
  27. }

HandlerExceptionResolver统一异常处理 返回JSON 和 ModelAndView的更多相关文章

  1. 自定义统一api返回json格式(app后台框架搭建三)

    在统一json自定义格式的方式有多种:1,直接重写@reposeBody的实现,2,自定义一个注解,自己去解析对象成为json字符串进行返回 第一种方式,我就不推荐,想弄得的话,可以自己去研究一下源码 ...

  2. Spring MVC全局异常后返回JSON异常数据

    问题: 当前项目是作为手机APP后台支持,使用spring mvc + mybaits + shiro进行开发.后台服务与手机端交互是发送JSON数据.如果后台发生异常,会直接返回异常页面,显示异常内 ...

  3. springmvc全局异常后返回JSON异常数据

    转自:http://www.cnblogs.com/exmyth/p/5601288.html (1)自定义或者使用spring自带的各种异常处理器 例如spring基于注解的异常解析器Annotat ...

  4. 配置springboot在访问404时自定义返回结果以及统一异常处理

    在搭建项目框架的时候用的是springboot,想统一处理异常,但是发现404的错误总是捕捉不到,总是返回的是springBoot自带的错误结果信息. 如下是springBoot自带的错误结果信息: ...

  5. 统一异常处理:HandlerExceptionResolver

    SpringExceptionResolver.java package com.mmall.common; import com.mmall.exception.PermissionExceptio ...

  6. spring boot 2 全局统一返回RESTful风格数据、统一异常处理

    全局统一返回RESTful风格数据,主要是实现ResponseBodyAdvice接口的方法,对返回值在输出之前进行修改.使用注解@RestControllerAdvice拦截异常并统一处理. 开发环 ...

  7. springboot统一返回json数据格式并配置系统异常拦截

    本文链接:https://blog.csdn.net/syystx/article/details/82870217通常进行前后端分离开发时我们需要定义统一的json数据交互格式并对系统未处理异常进行 ...

  8. SpringBoot系列(十)优雅的处理统一异常处理与统一结果返回

    SpringBoot系列(十)统一异常处理与统一结果返回 往期推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列 ...

  9. springboot实现定时任务,异步操作,统一结果返回,全局异常处理,拦截器及事务处理

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文都是springboot的常用和实用功能,话不多说开始吧 定时任务 1.启动类开启注解 @EnableScheduling //开启基于注解 ...

随机推荐

  1. CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries

    https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...

  2. MySQL数据库远程连接很慢的解决方案

    在开发机器上链接mysql数据库很慢,但是在数据库服务器上直接链接数据库很快.猜测应该是远程链接解析的问题,在查询MySQL相关文档和网络搜索后,发现了一个配置似乎可以解决这样的问题,就是在MySQL ...

  3. 七、新时间日期 API

    一.使用 LocalDate. LocalTime. LocalDateTime LocalDate. LocalTime. LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO- ...

  4. Redis学习一:Nosql入门和概述

    现在Redis越来越火,为了适应技术的发展,开始学习一下Redis,在学习Redis之前先学习一下Nosql. 第一部分:入门概述 1.1 互联网时代背景下大机遇,为什么用nosql 1.1.1 单机 ...

  5. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

  6. C++传递二维数字给一个自定义函数

    如果参数是多维数组,那么参数必须指明第一维意外得所有未得长度:比如你的 void tt(char a[][20])或者 void tt(char (*a)[20]) 另外这样也是可以的char *a[ ...

  7. Python练习-天已经亮了计算器也终于完成了

    # 编辑者:闫龙 import re #导入re模块(正则表达式) calc2 = "1-2*((60-30+(-40/52)*(9-2*5/3+7/3*-99/4*2998+10*568/ ...

  8. log4net记录系统错误日志到文本文件用法详解

    log4net是一个完全免费开源的插件,可以去官网下载源码. 一般系统操作日志不会用log4net,自己写代码存入数据库更方便合理,但是系统部署后运行在客户环境,难免会发生系统bug.崩溃.断网等无法 ...

  9. js工作常见问题收集

    1. viewport <meta name="viewport" content="width=device-width,initial-scale=1.0,mi ...

  10. PATH变量重复

    命令: export PATH=$(echo $PATH | tr : "\n"| sort | uniq | tr "\n" :) Code: awk -F: ...