当前位置:   article > 正文

SpringBoot实现自定义异常类。_springboot自定义异常

springboot自定义异常

本文分为两种方法,第一种适合于对于小程序这种简单的应用,只需要得到错误消息即可,第二章针对大型规范化的网页项目。

一、简易异常类封装:

1、创建自定义异常类

1、继承RuntimeException。

2、实现get和set方法(lombok工具类实现)

3、创建两个变量,一个用于保存状态码另一个保存错误消息。

4、创建可能使用到的构造方法

super(msg)表示将错误信息以我们平时看见的红色字样打印在控制台

  1. import lombok.Data;
  2. @Data//异常类
  3. public class EmosException extends RuntimeException{
  4. private int code=500;
  5. private String msg;
  6. //对该异常类的构造方法进行补充,不写的化会默认只有一个无参构造
  7. public EmosException(String msg) {
  8. super(msg);
  9. this.msg = msg;
  10. }
  11. public EmosException(String msg, int code) {
  12. super(msg);
  13. this.msg = msg;
  14. this.code = code;
  15. }
  16. public EmosException(String msg, Throwable e) {
  17. super(msg, e);
  18. this.msg = msg;
  19. }
  20. public EmosException(String msg, int code, Throwable e) {
  21. super(msg, e);
  22. this.msg = msg;
  23. this.code = code;
  24. }
  25. }

2、创建异常配置类

1、给这个类+@RestControllerAdvice注解表示是异常处理的配置类。

2、给该类的方法上+@ResponseBody注解表示返回的是JSON类型,@ExceptionHandler表示处理的异常是什么类型的异常。

3、书写异常处理方法,参数就是总异常类Exception。

4、用if else if等进行分支,用instanceof判断是什么类型的。

返回的类型都是字符串类型,保存在requset.data中,前台获取只需要request.data即可得到异常消息。

  1. package com.example.emos.config;
  2. import com.example.emos.exception.EmosException;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.apache.shiro.authz.UnauthorizedException;
  5. import org.springframework.http.HttpStatus;
  6. import org.springframework.web.bind.MethodArgumentNotValidException;
  7. import org.springframework.web.bind.annotation.ExceptionHandler;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import org.springframework.web.bind.annotation.ResponseStatus;
  10. import org.springframework.web.bind.annotation.RestControllerAdvice;
  11. @Slf4j//打印日志信息用
  12. @RestControllerAdvice//让系统知道这是处理异常的类
  13. //步骤:1、将异常转化为对应的类型 2、调用里面的获取消息模块
  14. public class ExceptionAdvice {
  15. @ResponseBody//将异常的返回格式为json格式
  16. @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  17. @ExceptionHandler(Exception.class)//处理哪种异常
  18. public String exceptionHandler(Exception e){
  19. log.error("执行异常",e);//将异常打印在控制台
  20. //处理后端验证失败
  21. if(e instanceof MethodArgumentNotValidException){
  22. //将异常强转为验证异常
  23. MethodArgumentNotValidException exception= (MethodArgumentNotValidException) e;
  24. //获取异常消息
  25. return exception.getBindingResult().getFieldError().getDefaultMessage();
  26. }
  27. //自定义异常
  28. else if(e instanceof EmosException){
  29. EmosException exception= (EmosException) e;
  30. return exception.getMsg();
  31. }
  32. //未授权类型
  33. else if(e instanceof UnauthorizedException){
  34. return "你不具备相关权限";
  35. }
  36. else{
  37. return "后端执行异常";
  38. }
  39. }
  40. }

二、复杂类型封装:

该封装方法将每一种异常对应的状态码,以及异常返回消息的统一封装

1、新建一个properties文件,用于保存所有的异常消息文本:

  1. lin.codes[0] = ok
  2. lin.codes[999] = 服务器未知异常
  3. lin.codes[10000] = 通用错误
  4. lin.codes[10001] = 通用参数错误
  5. lin.codes[10002] = 资源未找到
  6. lin.codes[10003] = 没有找到合适的登陆处理方法
  7. lin.codes[10004] = 令牌不合法或者过期
  8. lin.codes[10005] = 用户未被授权
  9. lin.codes[10006] = 登陆失败
  10. lin.codes[20000] = 用户类通用错误
  11. lin.codes[20001] = 用户已存在
  12. lin.codes[20002] = 用户不存在
  13. lin.codes[20003] = 用户密码错误
  14. lin.codes[20004] = 获取用户wx openid失败

2、写一个配置文件,将上面写好的各种异常消息在SpringBoot开启时就读取进去。

  1. package com.lin.missyou.core.CodeConfiguration;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.context.annotation.PropertySource;
  4. import org.springframework.stereotype.Component;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. //指明共有的前缀
  8. @ConfigurationProperties(prefix = "lin")
  9. //指明异常文件的地址
  10. @PropertySource(value = "classpath:config/exception-code.properties",encoding = "UTF-8")
  11. //加入到SpringBoot容器
  12. @Component
  13. //将那个文件的所有内容都读到这个map中
  14. public class ExceptionCodeConfiguration {
  15. private Map<Integer, String> codes = new HashMap<>();
  16. public Map<Integer, String> getCodes() {
  17. return codes;
  18. }
  19. public void setCodes(Map<Integer, String> codes) {
  20. this.codes = codes;
  21. }
  22. public String getMessage(int code){
  23. String message = codes.get(code);
  24. return message;
  25. }
  26. }

配置文件的位置如下:

3、此时我们新建一个父类继承RuntimeException,用于让所有的关于http的异常都继承它:

  1. package com.lin.missyou.exception.http;
  2. /**
  3. * 这是下面所有小错误类的父类。
  4. * 1、同包的所有类都继承这个类,不同异常的code和状态码不同。code码指的是前面写的异常信息的数组索引
  5. * 2、根据状态码对异常进行分类。
  6. * 3、例如商品没找到,或用户没找到,都抛出NotFoundException,状态码来表示是什么没找到
  7. * */
  8. public class HttpException extends RuntimeException{
  9. protected Integer code;
  10. protected Integer httpStatusCode = 500;
  11. public Integer getCode() {
  12. return code;
  13. }
  14. public Integer getHttpStatusCode() {
  15. return httpStatusCode;
  16. }
  17. }

 下面我们以一个NotFoundException为例:

  • 继承HttpException。
  • 编写一个有参构造
  1. package com.lin.missyou.exception.http;
  2. public class NotFoundException extends HttpException{
  3. public NotFoundException(int code){
  4. this.httpStatusCode = 404;
  5. this.code = code;
  6. }
  7. }

我还创建了一个和它写法一致的异常类,只是httpStatusCode不同:

 4、此时我们来到最核心的部分,全局异常管理类:

在这里将处理我们前面所写的全部异常,每当新增一个异常类就要在这里写好对应的处理方法。

1、打上@ControllerAdvice注解表示是处理异常类的

2、打上@ResponseBody 防止返回JSON对象出现问题

3、将刚刚写好的处理异常消息的封装类注入今来

4、@ExceptionHandler表示处理什么异常

5、@ResponseStatus表示该异常的http状态码是多少。该部分有两种处理方式:

  1. 通过@ResponseStatus注解直接指明对应的状态码
  2. 对于我们自己写的自定义异常类,由于以及指明了对应的httpStatus所以要通过ResponseEntity来返回。

完整代码:

  1. //当有异常时会进入这个类
  2. @ControllerAdvice //内部包含了Component注解,所以会被SpringBoot发现
  3. @ResponseBody //因为异常返回的也是对象,所以要加这个注解
  4. public class GlobalExceptionAdvice {
  5. @Autowired //将异常配置文件与这个类相对应
  6. private ExceptionCodeConfiguration codeConfiguration;
  7. //一、处理一个已知hpptStatus的异常
  8. @ExceptionHandler(value=Exception.class)
  9. /**
  10. * 设置Http的状态码,不设置的话都是200正常。设置方式有两种:
  11. * 1、 @ResponseStatus来设置状态码。不灵活,不能动态设置
  12. * 2、通过ResponseEntity来设置返回的属性
  13. * */
  14. @ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR)
  15. public UnifyResponse handleException(HttpServletRequest req, Exception e) {
  16. String requestUrl = req.getRequestURI(); //获取出现异常的地址
  17. String method = req.getMethod(); //获取是GET还是POST方法
  18. System.err.println(e);
  19. return new UnifyResponse(9999, "服务器异常", method + " "+ requestUrl);
  20. }
  21. //二、处理自己写的那些httpStatus动态变化HttpException<-自己写的那个父类
  22. @ExceptionHandler(HttpException.class)
  23. /**2、通过ResponseEntity来设置返回的属性(状态码等)*/
  24. public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest req, HttpException e){
  25. //1、获取URL和请求方法
  26. String requestUrl = req.getRequestURI();
  27. String method = req.getMethod();
  28. //2、封装返回对象
  29. UnifyResponse message =
  30. new UnifyResponse(
  31. e.getCode() //获取自定义的异常状态码
  32. ,codeConfiguration.getMessage(e.getCode()) //通过这个自定义状态码来查询对应的消息
  33. , method + " " + requestUrl); //封装方法和URL
  34. //3、因为没用指定状态码,所以需要用ResponseEntity对象。
  35. //3.1与ResponseBody注解用处相同,不加无法返回对象以及对中文等都无法解析
  36. HttpHeaders headers = new HttpHeaders();
  37. headers.setContentType(MediaType.APPLICATION_JSON);
  38. //3.2通过异常来获取http状态码信息
  39. HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());
  40. //4、返回对象
  41. return new ResponseEntity<>(message, headers, httpStatus);
  42. }
  43. }

调用处:

  1. @Override
  2. public BannerByNameVo findByName(String name) {
  3. BannerByNameVo bannerItems = bannerDao.selectByNames(name);
  4. if (bannerItems==null)
  5. throw new NotFoundException(10005);
  6. return bannerItems;
  7. }

返回形式如下:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/算法优化者/article/detail/62634
推荐阅读
相关标签
  

闽ICP备14008679号