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());
    }
}

目录
相关文章
|
24天前
|
前端开发 Java API
SpringBoot整合Flowable【06】- 查询历史数据
本文介绍了Flowable工作流引擎中历史数据的查询与管理。首先回顾了流程变量的应用场景及其局限性,引出表单在灵活定制流程中的重要性。接着详细讲解了如何通过Flowable的历史服务API查询用户的历史绩效数据,包括启动流程、执行任务和查询历史记录的具体步骤,并展示了如何将查询结果封装为更易理解的对象返回。最后总结了Flowable提供的丰富API及其灵活性,为后续学习驳回功能做了铺垫。
35 0
SpringBoot整合Flowable【06】- 查询历史数据
|
2月前
|
XML 安全 Java
|
3天前
|
Java 关系型数据库 MySQL
SpringBoot 通过集成 Flink CDC 来实时追踪 MySql 数据变动
通过详细的步骤和示例代码,您可以在 SpringBoot 项目中成功集成 Flink CDC,并实时追踪 MySQL 数据库的变动。
73 43
|
3月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
77 0
|
2月前
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2月前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
24天前
|
存储 前端开发 Java
SpringBoot整合Flowable【05】- 使用流程变量传递业务数据
本文介绍了如何使用Flowable的流程变量来管理绩效流程中的自定义数据。首先回顾了之前的简单绩效流程,指出现有流程缺乏分数输入和保存步骤。接着详细解释了流程变量的定义、分类(运行时变量和历史变量)及类型。通过具体代码示例展示了如何在绩效流程中插入全局和局部流程变量,实现各节点打分并维护分数的功能。最后总结了流程变量的使用场景及其在实际业务中的灵活性,并承诺将持续更新Flowable系列文章,帮助读者更好地理解和应用Flowable。 简要来说,本文通过实例讲解了如何利用Flowable的流程变量功能优化绩效评估流程,确保每个环节都能记录和更新分数,同时提供了全局和局部变量的对比和使用方法。
61 0
|
2月前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
71 14
|
3月前
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
78 5