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 容器
如何在SpringBoot项目中使用过滤器和拦截器
过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。
如何在SpringBoot项目中使用过滤器和拦截器
|
25天前
|
Java 关系型数据库 MySQL
创建一个SpringBoot项目,实现简单的CRUD功能和分页查询
【9月更文挑战第6天】该内容介绍如何使用 Spring Boot 实现具备 CRUD 功能及分页查询的项目。首先通过 Spring Initializr 创建项目并选择所需依赖;其次配置数据库连接,并创建实体类与数据访问层;接着构建服务层处理业务逻辑;最后创建控制器处理 HTTP 请求。分页查询可通过添加 URL 参数实现。
|
2月前
|
XML 前端开发 Java
基于SpringBoot 3.3实现任意文件在线预览功能的技术分享
【8月更文挑战第30天】在当今的数字化办公环境中,文件在线预览已成为提升工作效率、优化用户体验的重要功能之一。无论是文档、图片、PDF还是代码文件,用户都期望能够直接在浏览器中快速查看而无需下载。本文将围绕如何在Spring Boot 3.3框架下实现这一功能,分享一系列技术干货,助力开发者高效构建文件预览服务。
145 2
|
7天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
本文介绍了一个基于Spring Boot和Vue.js实现的在线考试系统。随着在线教育的发展,在线考试系统的重要性日益凸显。该系统不仅能提高教学效率,减轻教师负担,还为学生提供了灵活便捷的考试方式。技术栈包括Spring Boot、Vue.js、Element-UI等,支持多种角色登录,具备考试管理、题库管理、成绩查询等功能。系统采用前后端分离架构,具备高性能和扩展性,未来可进一步优化并引入AI技术提升智能化水平。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
|
9天前
|
Java 关系型数据库 MySQL
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术的房屋租赁系统,旨在通过自动化和信息化手段提升房屋管理效率,优化租户体验。系统采用JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Layui和Spring Boot 2.0等技术栈,实现了高效的房源管理和便捷的租户服务。通过该系统,房东可以轻松管理房源,租户可以快速找到合适的住所,双方都能享受数字化带来的便利。未来,系统将持续优化升级,提供更多完善的服务。
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
|
2天前
|
存储 前端开发 Java
Spring Boot 集成 MinIO 与 KKFile 实现文件预览功能
本文详细介绍如何在Spring Boot项目中集成MinIO对象存储系统与KKFileView文件预览工具,实现文件上传及在线预览功能。首先搭建MinIO服务器,并在Spring Boot中配置MinIO SDK进行文件管理;接着通过KKFileView提供文件预览服务,最终实现文档管理系统的高效文件处理能力。
|
3天前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
13 6
|
6天前
|
XML JSON Java
springboot文件上传,单文件上传和多文件上传,以及数据遍历和回显
本文介绍了在Spring Boot中如何实现文件上传,包括单文件和多文件上传的实现,文件上传的表单页面创建,接收上传文件的Controller层代码编写,以及上传成功后如何在页面上遍历并显示上传的文件。同时,还涉及了`MultipartFile`类的使用和`@RequestPart`注解,以及在`application.properties`中配置文件上传的相关参数。
springboot文件上传,单文件上传和多文件上传,以及数据遍历和回显
|
29天前
|
NoSQL 前端开发 Java
使用 Spring Boot + Neo4j 实现知识图谱功能开发
在数据驱动的时代,知识图谱作为一种强大的信息组织方式,正逐渐在各个领域展现出其独特的价值。本文将围绕使用Spring Boot结合Neo4j图数据库来实现知识图谱功能开发的技术细节进行分享,帮助读者理解并掌握这一技术栈在实际项目中的应用。
100 4
|
2月前
|
机器学习/深度学习 文字识别 前端开发
基于 Spring Boot 3.3 + OCR 实现图片转文字功能
【8月更文挑战第30天】在当今数字化信息时代,图像中的文字信息越来越重要。无论是文档扫描、名片识别,还是车辆牌照识别,OCR(Optical Character Recognition,光学字符识别)技术都发挥着关键作用。本文将围绕如何使用Spring Boot 3.3结合OCR技术,实现图片转文字的功能,分享工作学习中的技术干货。
78 2
下一篇
无影云桌面