springmvc-拦截器-异常处理

拦截器

SpringMVC 内置拦截器机制 ,允许在请求被目标方法处理的前后进行拦截,执行一些额外操作。

使用步骤: ①实现 HandlerInterceptor 接口的组件即可成为拦截器

②创建 WebMvcConfigurer 组件,并配置拦截器的拦截路径。

java 复制代码
@Component
//拦截器
public class MyHandlerInterceptor implements HandlerInterceptor {

//    目标方法执行之前
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyHandlerInterceptor.preHandle");
        return true; //true放行,false拦截
    }

//    目标方法执行完成之后
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, org.springframework.web.servlet.ModelAndView modelAndView) throws Exception {
        System.out.println("MyHandlerInterceptor.postHandle");
    }

//    页面渲染完后
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyHandlerInterceptor.afterCompletion");
    }
}
java 复制代码
/**
 * 拦截器需要配置,告诉spring,这个拦截器主要拦截什么
 *WebMvcConfigurer:专门对springmvc底层做一些配置
 *  容器需要有 WebMvcConfigurer组件
 *     方式1:@Bean 放一个 WebMvcConfigurer
 *     方式2:实现 WebMvcConfigurer接口
 */
@Configuration
public class MySpringMVCConfig implements WebMvcConfigurer {
    @Autowired
    private MyHandlerInterceptor myHandlerInterceptor;
//    添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myHandlerInterceptor).addPathPatterns("/**"); //拦截所有请求
    }
}

拦截器执行顺序

~当拦截器有多个时,执行顺序:

preHandle顺序执行------>postHandle逆序执行------>afterCompletion逆序执行。

~当postHandle、afterCompletion从哪炸炸了,倒序链路从哪结束。

~当某个preHandle返回false进行拦截时,

postHandle是目标方法执行之后执行,preHandle返回true时,afterCompletion才会执行。

画图

拦截器or过滤器

异常处理

~异常处理:

后端只编写正确的业务逻辑,如出现异常,通过抛异常方式提前中断业务逻辑,

让前端感知异常。

~异常处理最终方式:

  1. 必须有业务异常类(区分异常),

  2. 必须有异常枚举类,(列举项目中每个模块出现的所有异常)

  3. 编写业务代码的时候,只需要编写正确业务逻辑,如果出现预期问题,

使用抛异常方式(抛的时候把异常枚举一传),中断业务逻辑并通知上层controller

  1. GlobalExceptionHandler全局异常处理器捕获Controller层抛出的异常并处理,

全局拿到业务异常code msg 最终给前端响应。

java 复制代码
@Service
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    private EmployeeDao employeeDao;

    @Override
    public void updateEmployee(Employee employee) {
        Long id=employee.getId();
        if (id==null){
            throw new BuzException(BizExceptionEnume.ORDER_NOT_EXIST); //抛到业务异常类
        }
        employeeDao.updateEmp(employee);
}
java 复制代码
/**
 * 业务异常类
 */
@Data
public class BuzException extends  RuntimeException {
    private Integer code; //异常码
    private String msg; //异常信息

//    只传异常枚举对象
    public BuzException(BizExceptionEnume exceptionEnume){
        super(exceptionEnume.getMsg());
        System.out.println("业务异常类");
        this.code = exceptionEnume.getCode();
        this.msg = exceptionEnume.getMsg();
    }
}
java 复制代码
/**
 * 异常处理文档 枚举类
 *  将来修改的时候,很麻烦,得改很多地方,使用枚举类进行固化
 */
public enum BizExceptionEnume {
// 根据业务动态扩充
//    ORDER_xx订单模块相关异常
    ORDER_CLOSED(10001,"订单已关闭"),
    ORDER_NOT_EXIST(10002,"订单不存在"),
//    PRODUCT_xx商品模块相关异常
    PRODUCT_NOT_EXIST(10003,"库存不足"),
    PRODUCT_STOCK_ERROR(10004,"库存错误");
//    ...........

    @Getter
    private Integer code;
    @Getter
    private String msg;

    private BizExceptionEnume(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}
java 复制代码
/**
 * 全局异常处理- 只对controller层进行处理
 * @RestControllerAdvice合成注解<------@ResponseBody(R以json方式返回)、@ControllerAdvice(告诉springmvc这是一个全局异常处理类)
 */

@RestControllerAdvice
public class GlobalExceptionHandler {

//    业务异常
    @ExceptionHandler(BuzException.class)
    public R handleBizException(BuzException e){
        return R.error(e.getCode(), e.getMessage());
    }

    //    最终的兜底异常处理方法
    @ExceptionHandler(Throwable.class) //处理异常错误
    public R error(Exception e){
        return R.error(500, e.getMessage());
    }
}
相关推荐
customer084 分钟前
【开源免费】基于SpringBoot+Vue.JS租房管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
小学鸡!7 分钟前
spring中使用@Validated,什么是JSR 303数据校验,spring boot中怎么使用数据校验
java·spring boot
呼啦啦啦啦啦啦啦啦10 分钟前
【JVM】深入了解Java虚拟机-------内存划分、类加载机制、垃圾回收机制
java·jvm
顾北辰2010 分钟前
基本算法——聚类
java·spring boot·机器学习
DARLING Zero two♡13 分钟前
【优选算法】Sliding-Chakra:滑动窗口的算法流(下)
java·数据结构·c++·算法·leetcode
A XMan.2 小时前
JSON结构快捷转XML结构API集成指南
xml·java·前端·json·php
小林爱2 小时前
【Compose multiplatform教程06】用IDEA编译Compose Multiplatform常见问题
android·java·前端·kotlin·intellij-idea·compose·多平台
炸鸡配泡面5 小时前
Qt 12.28 day3
java·开发语言
get_money_5 小时前
代码随想录Day37 动态规划:完全背包理论基础,518.零钱兑换II,本周小结动态规划,377. 组合总和 Ⅳ,70. 爬楼梯(进阶版)。
java·笔记·算法·动态规划
get_money_5 小时前
代码随想录38 322. 零钱兑换,279.完全平方数,本周小结动态规划,139.单词拆分,动态规划:关于多重背包,你该了解这些!背包问题总结篇。
java·开发语言·笔记·算法·动态规划