SpringMVC&SpringBoot优雅的异常处理方式

一、背景

在SpringMVC和SpringBoot开发中,我们不可避免地要进行异常处理,目前SpringMVC框架也给我们提供了很多中异常处理地方式,今天介绍基于HandlerExceptionResolver接口处理所有异常。

二、准备工作

1.创建一个SpringBoot Web工程,编写一个简单的Controller

@RestController
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
    }

    @GetMapping("/test")
    public Result test(@RequestParam(value = "flag", defaultValue = "false") boolean flag) {
        if (flag) {
            throw BusinessException.error("业务异常信息");
        }
        return Result.success();
    }

}

2.提供一个统一返回格式

package com.example.demo.model;

import lombok.Data;

//返回实体封装
@Data
public class Result {
    private int status = 200;

    private String msg = "success";

    private String error;

    private Object data;

    private Result() {
    }

    public static Result success(String msg, Object data) {
        Result result = new Result();
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    public static Result success() {
        Result result = new Result();
        return result;
    }

    public static Result success(String msg) {
        Result result = new Result();
        result.setMsg(msg);
        return result;
    }


    public static Result error(String msg, String error) {
        Result result = new Result();
        result.setStatus(500);
        result.setMsg(msg);
        result.setError(error);
        return result;
    }

    public static Result error(String error) {
        Result result = new Result();
        result.setStatus(500);
        result.setError(error);
        return result;
    }
}

3.创建一个业务异常类

//处理业务异常
public class BusinessException extends RuntimeException {
    private BusinessException(String message) {
        super(message);
    }

    public static BusinessException error(String error){
        BusinessException exception = new BusinessException(error);
        return exception;
    }
}

4.编写一个自定义异常解析器


@Component
public class CustomHandlerExceptionResolver implements HandlerExceptionResolver, Ordered {
    // 设置优先级最高,由该异常解析器解析异常处理
    @Override
    public int getOrder() {
        return Integer.MIN_VALUE;
    }

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        Result error = Result.error("程序异常,请联系管理员!");

        // 处理业务异常
        if (ex instanceof BusinessException) {
            error.setError(ex.getMessage());
        }


        String json = "";
        try {
            ObjectMapper mapper = new ObjectMapper();
            json = mapper.writeValueAsString(error);
        } catch (JsonProcessingException e) {
            json = e.getMessage();
        }

        String finalJson = json;
        ModelAndView modelAndView = new ModelAndView();

        // 将异常信息封装成 View
        View view = (model, req, resp) -> {
            resp.setCharacterEncoding("UTF-8");
            resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            resp.setContentType("application/json;charset=utf-8");
            PrintWriter writer = resp.getWriter();
            writer.print(finalJson);
            writer.close();
        };

        modelAndView.setView(view);
        return modelAndView;
    }
}

三、测试

1.浏览器测试结果
在这里插入图片描述
2.使用postman模拟ajax请求结果
在这里插入图片描述

四、扩展

1.有的情况我们可能在没有进入到异常解析器,此时的异常会有tomcat请求转发一个新的请求,默认请求地址为:/error,在SpringBoot里面,我们可以参考org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController该类的处理方式,编写一个ErrorController的实现类作为controller来处理

2.对于采用前后端分离且涉及到分布式微服务开发的,开发过程中难免会遇到使用openFeign远程调用,而openFeign远程调用获取的返回值为Result格式,难免有点鸡肋,此时我们可以采用Aop来处理controller返回结果的类型,不过值得注意的是,采用该种方式所有controller的返回格式都应该是object。
五、源码地址
Gitee源码地址:https://gitee.com/shphuang/shphuang.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值