SpringMVC异常处理

首先介绍几个方法:能让我们更容易的理解下文

 SpringMVC 统一异常处理有三种方式,分别是:

  • 使用@ExceptionHandler注解

  • 实现HandlerExceptionResolver接口

  • 使用@controlleradvice注解

这里我就不介绍不常用的了,介绍一种比较实用的异常处理方式,通常以后工作也可以用到的

写之前需要导入SpringMVC包

User实体类的定义

 @Data
 @Builder
 @AllArgsConstructor
 @NoArgsConstructor
 public class User {
     private String username;
     private String password;
     private Integer id;
     private String names;
 }

第一步:编写自己的异常类 

public class MyException extends RuntimeException{
    private Integer code;

    public MyException (Integer code,String message){
        super(message);  //调用了父类的方法,所以我们不需要重写getter和setter方法
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}

第二步:编写响应数据实体类,并封装方法

这个实体类就是我们每次运行完方法之后返回给前端的数据对象,成功的时候返回编码为0,和data数据,异常的时候返回编码不为0,和错误信息message

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Resp {
    //返回的异常码
    private int code;
    //返回的异常信息
    private String message;
    //返回的正常数据
    private Object data;

    //成功需要传的对象
    public static Resp success(Object data){
        Resp resp = new Resp();
        resp.setData(data);
        return resp;
    }

    //异常时需要传的对象
    public static Resp error(int code,String message){
        Resp resp = new Resp();
        resp.setCode(code);
        resp.setMessage(message);
        return resp;
    }
}

第三步:编写控制类Controller类

在这里我使用了特殊的方式:字符串,其他对象照样可以转化的

@GetMapping("/s")
public String select(){
    return "你好";
}

第四步:编写处理异常类

简化来说就是:当我们运行时发生异常都会走到这里

@RestControllerAdvice
//异常处理
//实现ResponseBodyAdvice<Object>,主要是为了给Controller类中的方法实现增强
public class MyRestException implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        //true就是执行下面的beforeBodyWrite方法,false就是不执行下面的beforeBodyWrite方法
        return true;
    }

    @Override
    //Object o  就是Controller执行成功后返回的对象,也就是需要返回的数据data
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        //由于失败的时候也会走到这里,失败的相应对象已经被下面转成了json数据,又被系统当成了data数据,又包装了一次,所以判断是否是Resp类型,是的话直接返回
        if (o instanceof Resp){
            return o;
        }

        //既然控制成功的时候走到这里,我们可以在这里给控制器方法,增强,相当于切面
        Resp success = Resp.success(o);
        //由于String类型走过来的时候,也是被当作了Object,放入了Resp.success方法中,被封装成了json类型,而StringStringHttpMessageConverter只能处理String
        if (aClass == StringHttpMessageConverter.class){
            //我们自己判断如果为String类型的json转换器,就自己处理
            //利用了hutool工具类,JSONUtil.toJsonStr可以将任意对象(Bean、Map、集合等)直接转换为JSON字符串
            return JSONUtil.toJsonStr(success);
        }else {
            return success;
        }
    }

    @ExceptionHandler(Exception.class)
    public Object error(Exception e){
        int code = 999;
        //由于出错后就跑到这里了,而且是指定的异常,所以我们可以将Exception强转为我们指定的异常,方便取数据
        if (e instanceof MyException) {
            MyException ex = (MyException) e;
            code = ex.getCode();
        }
        return Resp.error(code,e.getMessage());
    }

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值