小言_互联网的博客

SpringBoot统一异常处理

304人阅读  评论(0)

本文为joshua317原创文章,转载请注明:转载自joshua317博客 SpringBoot统一异常处理 - joshua317的博客

一、背景

在做项目时,会产生各种各样业务异常,大致可以分为下面几类

1. 参数异常:服务端接收客户端参数时,参数不符合规则而产生的问题

2. 数据库异常:服务端和数据库交互时发生的异常

3. 业务异常:系统业务产生的问题

4. 未知异常:不属于以上三种异常的情况

异常根据自己的需要,进行增加,比如服务调用异常,服务错误异常、逻辑业务异常等等

二、解决思路

对项目异常进行分类编码,服务端需要将这些异常信息返回给客户端。 建立全局异常处理类,在类中针对不同类型异常进行返回值处理,包括默认返回结果。 在业务中,不同未知抛出不同异常

三、关键代码

全局异常处理


  
  1. @RestControllerAdvice
  2. @Slf4j
  3. public class GlobalExceptionHandler {
  4. /**
  5. *业务异常
  6. */
  7. @ExceptionHandler(BusinessException.class)
  8. public RetResult businessExceptionHandler (HttpServletRequest request, BusinessException e){
  9. if(Objects.nonNull(request)){
  10. StringBuffer requestUrlBuffer = request.getRequestURL();
  11. String method = request.getMethod();
  12. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  13. log.info( "BusinessException:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  14. }
  15. return ResultUtil.error(e.getCode(), e.getMessage());
  16. }
  17. /**
  18. *参数异常
  19. */
  20. @ExceptionHandler(ParamException.class)
  21. public RetResult paramExceptionHandler (HttpServletRequest request, ParamException e) {
  22. if (Objects.nonNull(request)) {
  23. StringBuffer requestUrlBuffer = request.getRequestURL();
  24. String method = request.getMethod();
  25. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  26. log.info( "ParamException:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  27. }
  28. return ResultUtil.error(e.getCode(), e.getMessage());
  29. }
  30. /**
  31. *数据库异常
  32. */
  33. @ExceptionHandler(DataBaseException.class)
  34. public RetResult databseExceptionHandler (HttpServletRequest request, DataBaseException e) {
  35. if (Objects.nonNull(request)) {
  36. StringBuffer requestUrlBuffer = request.getRequestURL();
  37. String method = request.getMethod();
  38. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  39. log.info( "DatabseExceptionHandler{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  40. }
  41. return ResultUtil.error(e.getCode(), e.getMessage());
  42. }
  43. @ExceptionHandler(RuntimeException.class)
  44. public RetResult runtimeExceptionHandler (HttpServletRequest request, RuntimeException e){
  45. if(Objects.nonNull(request)){
  46. StringBuffer requestUrlBuffer = request.getRequestURL();
  47. String method = request.getMethod();
  48. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  49. log.error( "RuntimeException:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  50. }
  51. return ResultUtil.error(EnumResultCode.UN_KNOW_ERROR.getCode(), e.getMessage());
  52. }
  53. @ExceptionHandler(Exception.class)
  54. public RetResult exceptionHandler (HttpServletRequest request, Exception e){
  55. if(Objects.nonNull(request)){
  56. StringBuffer requestUrlBuffer = request.getRequestURL();
  57. String method = request.getMethod();
  58. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  59. log.error( "Exception:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  60. }
  61. return ResultUtil.error(EnumResultCode.SYSTEM_ERROR.getCode(), e.getMessage());
  62. }
  63. }

四、具体代码

一共有以下几个文件

  • ParamException.java
  • BusinessException.java
  • DataBaseException.java
  • GlobalExceptionHandler.java
  • EnumResultCode.java
  • ResultUtil.java
  • RetResult.java
  • TestDemoController.java

1.ParamException.java


  
  1. package com.joshua317.share.exceptions;
  2. import com.joshua317.share.common.enums. EnumResultCode;
  3. import lombok. Getter;
  4. /**
  5. * 业务异常专用类
  6. */
  7. @Getter
  8. public class ParamException extends RuntimeException {
  9. private String code;
  10. private String message;
  11. public ParamException( String message) {
  12. super(message);
  13. this.code = EnumResultCode. PARAM_ERROR.getCode();
  14. this.message = message;
  15. }
  16. }

2.BusinessException.java


  
  1. package com.joshua317.manager.exce;
  2. import com.joshua317.share.common.enums. EnumResultCode;
  3. import lombok. Getter;
  4. /**
  5. * 业务异常专用类
  6. */
  7. @Getter
  8. public class BusinessException extends RuntimeException {
  9. private String code;
  10. private String message;
  11. public BusinessException(int code, String message) {
  12. super(message);
  13. this.code = code;
  14. this.message = message;
  15. }
  16. public BusinessException( String message) {
  17. super(message);
  18. this.code = EnumResultCode. BUSINESS_ERROR.getCode();
  19. this.message = message;
  20. }
  21. public BusinessException( EnumResultCode resultCode) {
  22. super(resultCode.getMessage());
  23. this.code = resultCode.getCode();
  24. this.message = resultCode.getMessage();
  25. }
  26. }

3.DataBaseException.java


  
  1. package com.joshua317.share.exceptions;
  2. import com.joshua317.share.common.enums. EnumResultCode;
  3. import lombok. Getter;
  4. /**
  5. * 业务异常专用类
  6. */
  7. @Getter
  8. public class DataBaseException extends RuntimeException {
  9. private String code;
  10. private String message;
  11. public DataBaseException() {
  12. super(message);
  13. this.code = EnumResultCode. DATABASE_ERROR.getCode();
  14. this.message = EnumResultCode. DATABASE_ERROR.getMessage();
  15. }
  16. }

4.GlobalExceptionHandler.java


  
  1. package com.joshua317.manager.exce;
  2. import com.joshua317.lib.response.exception.ApiException;
  3. import com.joshua317.share.common.enums.EnumResultCode;
  4. import com.joshua317.share.model.bean.RetResult;
  5. import com.joshua317.share.utils.ResultUtil;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.springframework.web.bind.annotation.ExceptionHandler;
  8. import org.springframework.web.bind.annotation.RestControllerAdvice;
  9. import javax.servlet.http.HttpServletRequest;
  10. import java.util.Objects;
  11. @RestControllerAdvice
  12. @Slf4j
  13. public class GlobalExceptionHandler {
  14. /**
  15. *业务异常
  16. */
  17. @ExceptionHandler(BusinessException.class)
  18. public RetResult businessExceptionHandler (HttpServletRequest request, BusinessException e){
  19. if(Objects.nonNull(request)){
  20. StringBuffer requestUrlBuffer = request.getRequestURL();
  21. String method = request.getMethod();
  22. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  23. log.info( "BusinessException:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  24. }
  25. return ResultUtil.error(e.getCode(), e.getMessage());
  26. }
  27. /**
  28. *参数异常
  29. */
  30. @ExceptionHandler(ParamException.class)
  31. public RetResult paramExceptionHandler (HttpServletRequest request, ParamException e) {
  32. if (Objects.nonNull(request)) {
  33. StringBuffer requestUrlBuffer = request.getRequestURL();
  34. String method = request.getMethod();
  35. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  36. log.info( "ParamException:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  37. }
  38. return ResultUtil.error(e.getCode(), e.getMessage());
  39. }
  40. /**
  41. *数据库异常
  42. */
  43. @ExceptionHandler(DataBaseException.class)
  44. public RetResult databseExceptionHandler (HttpServletRequest request, DataBaseException e) {
  45. if (Objects.nonNull(request)) {
  46. StringBuffer requestUrlBuffer = request.getRequestURL();
  47. String method = request.getMethod();
  48. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  49. log.info( "DatabseExceptionHandler{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  50. }
  51. return ResultUtil.error(e.getCode(), e.getMessage());
  52. }
  53. @ExceptionHandler(RuntimeException.class)
  54. public RetResult runtimeExceptionHandler (HttpServletRequest request, RuntimeException e){
  55. if(Objects.nonNull(request)){
  56. StringBuffer requestUrlBuffer = request.getRequestURL();
  57. String method = request.getMethod();
  58. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  59. log.error( "RuntimeException:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  60. }
  61. return ResultUtil.error(EnumResultCode.UN_KNOW_ERROR.getCode(), e.getMessage());
  62. }
  63. @ExceptionHandler(Exception.class)
  64. public RetResult exceptionHandler (HttpServletRequest request, Exception e){
  65. if(Objects.nonNull(request)){
  66. StringBuffer requestUrlBuffer = request.getRequestURL();
  67. String method = request.getMethod();
  68. String requestUrl = Objects.isNull(requestUrlBuffer) ? request.getRequestURI() : requestUrlBuffer.toString();
  69. log.error( "Exception:{}, \n请求URL: [{}], \n请求方式: [{}]\n", e.getMessage(), requestUrl, method, e);
  70. }
  71. return ResultUtil.error(EnumResultCode.SYSTEM_ERROR.getCode(), e.getMessage());
  72. }
  73. }

5.EnumResultCode.java


  
  1. package com. joshua317. manager. exce;
  2. import lombok. Getter;
  3. @Getter
  4. public enum EnumResultCode {
  5. //成功
  6. SUCCESS( "0", "成功"),
  7. //错误
  8. FALSE( "1", "错误"),
  9. PARAM_ERROR( "C_1", "参数异常"),
  10. //内部错误
  11. BUSINESS_ERROR( "C_2", "业务异常"),
  12. DATABASE_ERROR( "SYS_1", "数据库异常"),
  13. //token超时
  14. TOKEN_INVALID( "AUTH_0", "token无效或已超时");
  15. private String code;
  16. private String message;
  17. EnumResultCode( String code, String message) {
  18. this. code = code;
  19. this. message = message;
  20. }
  21. }

6.ResultUtil.java


  
  1. package com.joshua317.manager.exce;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import org.apache.http.HttpStatus;
  5. import javax.servlet.ServletRequest;
  6. import javax.servlet.ServletResponse;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import java.io.IOException;
  10. /**
  11. * @author joshua317
  12. * @Description: 返回结果工具
  13. */
  14. public class ResultUtil {
  15. public static RetResult success (Object obj) {
  16. RetResult res = new RetResult();
  17. res.setCode(EnumResultCode.SUCCESS.getCode());
  18. res.setMsg(EnumResultCode.SUCCESS.getMessage());
  19. res.setData(obj);
  20. return res;
  21. }
  22. public static RetResult success (String msg) {
  23. RetResult res = new RetResult();
  24. res.setCode(EnumResultCode.SUCCESS.getCode());
  25. res.setData( null);
  26. res.setMsg(msg);
  27. return res;
  28. }
  29. public static RetResult success (Object obj, String msg) {
  30. RetResult res = new RetResult();
  31. res.setCode(EnumResultCode.SUCCESS.getCode());
  32. res.setMsg(msg);
  33. res.setData(obj);
  34. return res;
  35. }
  36. public static RetResult success (Integer code, Object obj, String msg) {
  37. RetResult res = new RetResult();
  38. res.setCode(code);
  39. res.setMsg(msg);
  40. res.setData(obj);
  41. return res;
  42. }
  43. public static RetResult success (Object obj, long pageTotal) {
  44. RetResult res = new RetResult();
  45. res.setCode(EnumResultCode.SUCCESS.getCode());
  46. res.setMsg(EnumResultCode.SUCCESS.getMessage());
  47. res.setData(obj);
  48. res.setPageTotal(pageTotal);
  49. return res;
  50. }
  51. public static RetResult success (EnumResultCode exceptionCode, Object obj, long pageTotal) {
  52. RetResult res = new RetResult();
  53. res.setCode(exceptionCode.getCode());
  54. res.setMsg(exceptionCode.getMessage());
  55. res.setData(obj);
  56. res.setPageTotal(pageTotal);
  57. return res;
  58. }
  59. public static RetResult success (Integer code, Object obj, String msg, long pageTotal) {
  60. RetResult res = new RetResult();
  61. res.setCode(code);
  62. res.setMsg(msg);
  63. res.setData(obj);
  64. res.setPageTotal(pageTotal);
  65. return res;
  66. }
  67. public static RetResult success () {
  68. return success(EnumResultCode.SUCCESS.getMessage());
  69. }
  70. public static RetResult error (String msg) {
  71. RetResult res = new RetResult();
  72. res.setCode(EnumResultCode.SYSTEM_ERROR.getCode());
  73. res.setMsg(msg);
  74. return res;
  75. }
  76. public static RetResult error (Integer code, String msg) {
  77. RetResult res = new RetResult();
  78. res.setCode(code);
  79. res.setMsg(msg);
  80. return res;
  81. }
  82. public static RetResult error (EnumResultCode exceptionCode) {
  83. RetResult res = new RetResult();
  84. res.setCode(exceptionCode.getCode());
  85. res.setMsg(exceptionCode.getMessage());
  86. return res;
  87. }
  88. public static RetResult error (Integer code, String msg, Object obj) {
  89. RetResult res = new RetResult();
  90. res.setCode(code);
  91. res.setData(obj);
  92. res.setMsg(msg);
  93. return res;
  94. }
  95. public static RetResult error (Integer code, String msg, Object obj, int pageTotal) {
  96. RetResult res = new RetResult();
  97. res.setCode(code);
  98. res.setData(obj);
  99. res.setMsg(msg);
  100. res.setPageTotal(pageTotal);
  101. return res;
  102. }
  103. public static HttpServletResponse getResponse (ServletRequest request, ServletResponse response, RetResult retResult) throws IOException {
  104. Gson gson = new GsonBuilder().create();
  105. String resultString = gson.toJson(retResult);
  106. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  107. HttpServletResponse httpServletResponse = (HttpServletResponse) response;
  108. httpServletResponse.setHeader( "Access-control-Allow-Origin", httpServletRequest.getHeader( "Origin"));
  109. httpServletResponse.setHeader( "Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
  110. httpServletResponse.setHeader( "Access-Control-Allow-Headers", httpServletRequest.getHeader( "Access-Control-Request-Headers"));
  111. httpServletResponse.setCharacterEncoding( "UTF-8");
  112. httpServletResponse.setContentType( "application/json;charset=UTF-8");
  113. httpServletResponse.setStatus(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION);
  114. httpServletResponse.getWriter().write(resultString);
  115. return httpServletResponse;
  116. }
  117. }

7.RetResult.java


  
  1. package com.joshua317.manager.exce;
  2. import lombok.Data;
  3. /**
  4. * @author joshua317
  5. * @Description: 权限请求 返回结果
  6. */
  7. @Data
  8. public class RetResult {
  9. private String code;
  10. private String msg;
  11. private Object data;
  12. private long pageTotal; //分页时:查询数据数量
  13. public RetResult() {
  14. this.code = "0";
  15. this.msg = "";
  16. this. data = null;
  17. this.pageTotal = 0;
  18. }
  19. /**
  20. * 返回状态码、信息、以及数据
  21. */
  22. public RetResult(String code, String msg, Object data) {
  23. this.code = code;
  24. this.msg = msg;
  25. this. data = data;
  26. this.pageTotal = 0;
  27. }
  28. /**
  29. * 返回状态码、信息、以及数据量
  30. */
  31. public RetResult(String code, String msg, Object data, int pageSize) {
  32. this.code = code;
  33. this.msg = msg;
  34. this. data = data;
  35. this.pageTotal = pageSize;
  36. }
  37. /**
  38. * 只返回状态码,以及信息可以用于失败时候来使用
  39. */
  40. public RetResult(String code, String msg) {
  41. this.code = code;
  42. this.msg = msg;
  43. this. data = null;
  44. this.pageTotal = 0;
  45. }
  46. /**
  47. * 只返回状态码和数据
  48. */
  49. public RetResult(String code, Object data) {
  50. this.code = code;
  51. this.msg = "";
  52. this. data = data;
  53. this.pageTotal = 0;
  54. }
  55. }

8.TestDemoController.java


  
  1. package com.joshua317.manager.exce;
  2. import cn.hutool.core.util.StrUtil;
  3. import io.swagger.annotations.Api;
  4. import io.swagger.annotations.ApiOperation;
  5. import org.springframework.web.bind. annotation.*;
  6. /*
  7. * @Description 测试接口
  8. * @Author joshua317
  9. **/
  10. @Api(value = "测试接口")
  11. @RequestMapping("/demo")
  12. @RestController
  13. public class TestDemoController {
  14. /**
  15. * 新增
  16. *
  17. * @param code 编号
  18. * @return
  19. */
  20. @ApiOperation(value = "新增")
  21. @PostMapping("/save")
  22. public RetResult find( @RequestParam("code") String code) {
  23. if (StrUtil.isEmpty(code)) {
  24. throw new BusinessException( "code不能为空");
  25. }
  26. return ResultUtil.success( "新增成功");
  27. }
  28. }

本文为joshua317原创文章,转载请注明:转载自joshua317博客 SpringBoot统一异常处理 - joshua317的博客


转载:https://blog.csdn.net/joshua317/article/details/128259600
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场