@ControllerAdvice 用法

目录

@ControllerAdvice 用法

1、全局异常处理

2、添加全局数据


@ControllerAdvice 用法

顾名思义,@ControllerAdvice就是@Controller 的增强版。@ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用。

1、全局异常处理

@ControllerAdvice最常见的使用场景就是全局异常处理。比如文件上传大小限制的配置,如果用户上传的文件超过了限制大小,就会抛出异常,此时可以通过@ControllerAdvice结合@ExceptionHandler定义全局异常捕获机制,代码如下:

import lombok.extern.slf4j.Slf4j;
import net.xdclass.util.JsonData;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@ControllerAdvice // 需要返回ResponseBody
// @RestControllerAdvice 直接返回Json数据不用返回ResponseBody
@Slf4j
public class CustomExceptionHandler {

    // 自定义异常
    @ExceptionHandler(value = Exception.class) // 要捕获哪种异常
    @ResponseBody // 要是用上面的 @RestControllerAdvice 就不用加此注解
    public JsonData handler(Exception e) {
        if (e instanceof RuntimeException) { // 判断是不是其子类
            BizException bizException = (BizException) e;
            log.error("[业务异常]{}", e);
            return JsonData.buildCodeAndMsg(bizException.getCode(), bizException.getMsg());
        } else {
            log.error("[系统异常]{},e");
            return JsonData.buildError("系统异常");
        }
    }

}

附 BizException.class,代码如下

import lombok.Data;
import net.xdclass.enums.BizCodeEnum;

@Data
public class BizException extends RuntimeException {

    private int code;

    private String msg;

    // 构造函数
    public BizException(Integer code, String message) {
        super(message);
        this.code = code;
        this.msg = message;
    }

    // 构造函数
    public BizException(BizCodeEnum bizCodeEnum) {
        super(bizCodeEnum.getMessage());
        this.code = bizCodeEnum.getCode();
        this.msg = bizCodeEnum.getMessage();
    }

}

自定义异常枚举类 BizCodeEnum.java

public enum BizCodeEnum {

    /**
     * 短链分组
     */
    GROUP_REPEAT(23001, "分组名重复"),
    GROUP_OPER_FAIL(23503, "分组名操作失败"),
    GROUP_NOT_EXIST(23404, "分组不存在"),

    /**
     * 验证码
     */
    CODE_TO_ERROR(240001, "接收号码不合规"),
    CODE_LIMITED(240002, "验证码发送过快"),
    CODE_ERROR(240003, "验证码错误"),
    CODE_CAPTCHA_ERROR(240101, "图形验证码错误"),

    /**
     * 账号
     */
    ACCOUNT_REPEAT(250001, "账号已经存在"),
    ACCOUNT_UNREGISTER(250002, "账号不存在"),
    ACCOUNT_PWD_ERROR(250003, "账号或者密码错误"),
    ACCOUNT_UNLOGIN(250004, "账号未登录"),

    /**
     * 短链
     */
    SHORT_LINK_NOT_EXIST(260404, "短链不存在"),

    /**
     * 订单
     */
    ORDER_CONFIRM_PRICE_FAIL(280002, "创建订单-验价失败"),
    ORDER_CONFIRM_REPEAT(280008, "订单恶意-重复提交"),
    ORDER_CONFIRM_TOKEN_EQUAL_FAIL(280009, "订单令牌缺少"),
    ORDER_CONFIRM_NOT_EXIST(280010, "订单不存在"),

    /**
     * 支付
     */
    PAY_ORDER_FAIL(300001, "创建支付订单失败"),
    PAY_ORDER_CALLBACK_SIGN_FAIL(300002, "支付订单回调验证签失败"),
    PAY_ORDER_CALLBACK_NOT_SUCCESS(300003, "支付宝回调更新订单失败"),
    PAY_ORDER_NOT_EXIST(300005, "订单不存在"),
    PAY_ORDER_STATE_ERROR(300006, "订单状态不正常"),
    PAY_ORDER_PAY_TIMEOUT(300007, "订单支付超时"),

    /**
     * 流控操作
     */
    CONTROL_FLOW(500101, "限流控制"),
    CONTROL_DEGRADE(500201, "降级控制"),
    CONTROL_AUTH(500301, "认证控制"),

    /**
     * 流量包操作
     */
    TRAFFIC_FREE_NOT_EXIST(600101, "免费流量包不存在,联系客服"),
    TRAFFIC_REDUCE_FAIL(600102, "流量不足,扣减失败"),
    TRAFFIC_EXCEPTION(600103, "流量包数据异常,用户无流量包"),

    /**
     * 通用操作码
     */
    OPS_REPEAT(110001, "重复操作"),
    OPS_NETWORK_ADDRESS_ERROR(110002, "网络地址错误"),

    /**
     * 文件相关
     */
    FILE_UPLOAD_USER_IMG_FAIL(700101, "用户头像文件上传失败");

    private String message;

    private int code;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getCode() {
        return code;
    }

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

    BizCodeEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }

}

只需在系统中定义CustomExceptionHandler类,然后添加@ControllerAdvice注解即可。当系统启动时,该类就会被扫描到Spring容器中,然后定义handler方法,在该方法上添加了@ExceptionHandler注解,其中定义的Exception.class 表明该方法用来处理所有类型的异常。如果想让该方法处理所有类型的异常,只需将Exception改为 其他Exception即可。方法的参数可以有异常实例、HttpServletResponse以及HttpServletRequest、Model 等,返回值可以是一段JSON、一个ModelAndView、一个逻辑视图名等。

2、添加全局数据

@ControllerAdvice是一个全局数据处理组件,因此也可以在@ControllerAdvice中配置全局数据,使用@ModelAttribute注解进行配置,代码如下:

@ControllerAdvice
public class GlobalConfig {
    @ModelAttribute(value = "info")
    public Map<String, String> userInfo() {
        HashMap<String, String> map = new HashMap<>();
        map.put("username", "罗贯中");
        map.put("gender", "男");
        return map;
    }
}

代码解释:

  • 在全局配置中添加userInfo方法,返回一个map。该方法有一个注解@ModelAttribute,其中的value属性表示这条返回数据的key,而方法的返回值是返回数据的value。
  • 此时在任意请求的Controller 中,通过方法参数中的Model都可以获取info 的数据。

Controller 例代码如下:

public class MyController {
    @GetMapping("/hello")
    @ResponseBody
    public void hello(Model model) {
        Map<String, Object> map = model.asMap();
        Set<String> keySet = map.keySet();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            Object value = map.get(key);
            System.out.println(key + ">>>>>" + value);
        }
    }
}

 在请求方法中,将Model 中的数据打印出来,如图所示。

在这里插入图片描述

还有其他用法见转载链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值