Spring Boot统一功能处理(拦截器, 统一数据返回格式, 统一异常处理)

简介: Spring Boot统一功能处理(拦截器, 统一数据返回格式, 统一异常处理)

Spring Boot 中的几种统一功能处理方式 (共性下沉, 个性提取)

  1. 拦截器
  2. 统一数据返回格式
  3. 统一异常处理

拦截器

Spring MVC 中的一个组件, 用来拦截用户的请求, 在指定方法前后, 根据业务需要执行预先设定的代码

拦截器的使用步骤

  1. 定义拦截器
  2. 注册配置拦截器

定义拦截器

实现 HandlerInterceptor 接口, 并重写其所有方法

preHandler() 方法 : 在目标方法执行前执行 , 返回值 true 表示允许继续执行目标方法, 返回值 false 表示中断目标方法的执行

postHandler() 方法 : 目标方法执行后执行


afterCompletion() 方法 : 视图渲染完成后, 执行该方法内容

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("LoginInterceptor 目标方法执行前, 执行代码 ...");
        return true; // 默认全部放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("LoginInterceptor 目标方法执行后, 执行代码 ...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("LoginInterceptor 视图渲染完成后, 执行代码 ...");
    }
}

注册配置拦截器

实现 WebMvcConfigurer 接口, 并重写 addInterceptors 方法


@Configuration
public class WebConfig implements WebMvcConfigurer {
    // 获取拦截器对象
    @Autowired
    private LoginInterceptor loginInterceptor;

    private List<String> excludePath = Arrays.asList(
            "user/login",
            "/**/**.html",
            "/css/**",
            "/js/**",
            "/img/**"
    );
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册自定义拦截对象
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")  // 设置拦截器的拦截路径
                .excludePathPatterns("/login.html") // 设置拦截器的放行路径
                .excludePathPatterns(excludePath);
    }
}


常见拦截路径的设置 :

/* : 一级路径

/** : 任意级路径

/book/* : /book 下的一级路径

/book/** : /book 下的任意级路径

添加拦截器之后的执行流程

  1. 添加拦截器后, 在执行每个方法之前, 都会先进行判定是否在拦截路径 / 放行路径中, 并判定是否执行拦截器内容
  2. 被拦截住的请求, 会先执行 preHandler() 方法, 该方法返回一个布尔值. 返回 true 代表该方法被放行, 返回 false 表示该方法不会被放行(即不会执行)
  3. 请求执行完毕后, 再执行 postHandler() 方法
  4. 待视图渲染完成后, 再执行afterComletion() 方法

统一数据返回格式

统一数据返回格式使用 @ControllerAdvice 和 实现 ResponseBodyAdvice 接口的方式实现

@ControllerAdvice : 表示该类为 控制器通知类

ResponseBodyAdvice 接口 : 内含 supports 方法beforeBodyWrite 方法

  • supports : 判断是否执行 beforeBodyWtire 方法, 返回值为 true 为执行, false 为不执行.
  • ResponseBodyWrite : 对 response 方法进行具体操作处理

统一数据返回格式优点

  1. 方便前端程序员接收和解析后端数据接口返回的数据
  1. 方便后端部门的统一规范的标准执行
  2. 有利于项目统一数据的维护和修改

首先得有一个数据返回格式

@Data
public class Result<T> {
    private int status;
    private String err = "";
    private T data;

    //成功
    public static <T>Result<T> success(T data) {
        Result<T> result = new Result<T>();
        result.setStatus(200);
        result.setData(data);
        return result;
    }

    // 失败
    public static <T>Result<T> fail(T data, String err) {
        Result<T> result = new Result<T>();
        result.setStatus(-1);
        result.setErr(err);
        result.setData(data);
        return result;
    }
    public static <T>Result<T> fail(String err) {
        Result<T> result = new Result<T>();
        result.setStatus(-1);
        result.setErr(err);
        return result;
    }

    // 未登录
    public static <T>Result<T> unlogin() {
        Result<T> result = new Result<T>();
        result.setStatus(-2);
        result.setErr("用户未登录");
        return result;
    }
}

统一数据格式 具体执行代码

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        // 表示对哪些请求执行 统一数据返回格式处理 (这里就简单的全部执行)
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if(body instanceof Result) {
            return body;
        }
        if(body instanceof String) {
            // 需要对 String 类型的 body 进行序列化处理 (使用 Spring Boot 内置的 Jackson 工具)
            return objectMapper.writeValueAsString(Result.success(body));
        }
        return Result.success(body);
    }
}

统一异常处理

统一异常处理使用 @ControllerAdvice@ExceptionHandler 注解实现

@ControllerAdvice : 表示控制器通知类

@ExceptionHandler : 表示异常处理器

两个注解搭配使用, 表示当出现某个异常的时候, 执行对应的方法事件

@ResponseBody
@ControllerAdvice
public class ErrorAdvice {
    @ExceptionHandler
    public Result handler(Exception e) {
        return Result.fail(e.getMessage());
    }

    @ExceptionHandler
    public Result handler(NullPointerException e) {
        return Result.fail("发生空指针异常: " + e.getMessage());
    }

    @ExceptionHandler
    public Result handler(ArithmeticException e) {
        return Result.fail("发生算数异常:" + e.getMessage());
    }
}

目录
相关文章
|
1天前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
|
11天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的多功能智能手机阅读APP的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的多功能智能手机阅读APP的详细设计和实现(源码+lw+部署文档+讲解等)
|
14天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的多功能智能手机阅读APP附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的多功能智能手机阅读APP附带文章源码部署视频讲解等
17 1
|
19天前
|
Java 数据库连接 Maven
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
|
18天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的高校党建基本数据管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的高校党建基本数据管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
15 1
|
19天前
|
物联网
好的资源链接,gitee全糖咖啡,B站视频转成mp4,全糖咖啡 / 物联网网关数据上传,,全糖咖啡 / springboot+百度智能车牌检测
好的资源链接,gitee全糖咖啡,B站视频转成mp4,全糖咖啡 / 物联网网关数据上传,,全糖咖啡 / springboot+百度智能车牌检测
|
21天前
|
开发框架 Java 开发者
Spring框架的最新功能与应用案例解析
Spring框架的最新功能与应用案例解析
|
1天前
|
Java Spring
Spring框架使用了哪些技术来实现其核心功能
Spring框架使用了哪些技术来实现其核心功能?
|
18天前
|
Java 微服务 Spring
微服务04---服务远程调用,根据订单id查询订单功能,根据id查询订单的同时,把订单所属的用户信息一起返回,Spring提供了一个工具RestTemplate,Bean写在对象前面,以后可以在任何地
微服务04---服务远程调用,根据订单id查询订单功能,根据id查询订单的同时,把订单所属的用户信息一起返回,Spring提供了一个工具RestTemplate,Bean写在对象前面,以后可以在任何地
|
19天前
|
存储 Java
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不