优雅!使用 Spring Boot 3.3 + @ControllerAdvice 实现全局数据绑定与预处理

科技   2024-10-20 07:30   北京  


优雅!使用 Spring Boot 3.3 + @ControllerAdvice 实现全局数据绑定与预处理

在现代 Web 应用中,数据的传递与处理往往需要全局化处理,尤其是涉及到类似于用户信息、网站通用配置等数据时,开发者通常需要在多个控制器和页面中共享这些数据。传统的方式是在每个控制器或页面中重复传递这些信息,这种做法显然不够优雅,也增加了维护成本。为了解决这一问题,Spring Framework 提供了 @ControllerAdvice 注解,可以在全局范围内实现数据绑定与预处理,从而极大地简化代码结构。

@ControllerAdvice 是 Spring 提供的一个专门用于处理全局范围内的控制器逻辑增强的注解。它可以用来处理全局异常、全局数据绑定、全局权限校验等功能。在本文中,我们将重点讲解如何使用 @ControllerAdvice 结合 @ModelAttribute 实现全局数据绑定,将应用的一些全局配置数据注入到所有控制器和视图中。此外,我们还会结合前端 jQuery 调用 JSON 接口动态加载数据,并优化控制器类的设计。

@ControllerAdvice 注解的详细用法

@ControllerAdvice 的核心功能是在不修改现有控制器逻辑的前提下,增强其功能。通过 @ControllerAdvice,我们可以统一处理如下几种场景:

  1. 全局异常处理:可以集中捕获并处理所有控制器的异常。

  2. 全局数据绑定:可以为所有控制器统一注入公共数据,避免重复代码。

  3. 全局权限校验:在控制器逻辑执行之前进行统一的权限检查。

运行效果:

若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。

项目配置

Maven 配置(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icoderoad</groupId>
<artifactId>global-binding</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>global-binding</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Spring Boot Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Thymeleaf 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<!-- Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<!-- Spring Boot 配置处理依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

YAML 配置(application.yaml)

在 application.yaml 中,我们配置了全局的数据,例如应用名称、页面标题等,这些配置将会通过 @ControllerAdvice 进行全局绑定。

app:
name: "ICodeRoad"
title: "Spring Boot 全局数据绑定示例"

配置类(AppProperties.java)

我们通过 @ConfigurationProperties 注解读取 YAML 文件中的自定义配置。Lombok 用于简化实体类代码。

package com.icoderoad.global.binding.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private String title;
}

全局数据绑定(GlobalDataBinder.java)

@ControllerAdvice 用于定义全局范围的控制器建议,这里我们实现了全局数据绑定,将 AppProperties 中的配置数据传递到每一个视图中。

package com.icoderoad.global.binding.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;

import com.icoderoad.global.binding.config.AppProperties;

@ControllerAdvice
public class GlobalDataBinder {

@Autowired
private AppProperties appProperties;

/**
* 将应用程序的全局数据绑定到所有的模型中
*/

@ModelAttribute("appName")
public String getAppName() {
return appProperties.getName();
}

@ModelAttribute("appTitle")
public String getAppTitle() {
return appProperties.getTitle();
}
}

控制器类(HomeController.java)

创建一个简单的控制器来渲染主页,并验证全局数据绑定的效果。

package com.icoderoad.global.binding.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.icoderoad.global.binding.config.AppProperties;

/**
* 处理首页和数据接口的控制器
*/

@RestController
@RequestMapping("/api")
public class HomeController {

@Autowired
private AppProperties appProperties;

/**
* 返回首页信息的 JSON 数据
*/

@GetMapping("/app-info")
public AppProperties getAppInfo() {
// 直接返回 AppProperties 对象作为 JSON 响应
return appProperties;
}
}

在这个控制器中,/api/app-info 接口会返回全局配置信息(AppProperties)的 JSON 数据,供前端通过 jQuery 进行动态加载。

前端代码

在前端页面中,我们使用 jQuery 通过 AJAX 请求动态加载后端的 JSON 数据,并将其显示在页面中。使用了 Bootstrap 来进行页面的简单布局,并通过 CDN 方式加载 jQuery 和 Bootstrap 的资源。

在 src/main/resources/templates/ 目录下创建 index.html 文件,使用 Thymeleaf 渲染全局绑定的数据。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全局数据绑定</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1 id="appTitle">加载中...</h1>
<p>欢迎来到 <span id="appName">加载中...</span> 的主页!</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>

<script>
$(document).ready(function () {
// 使用 jQuery 的 Ajax 请求从后端获取应用程序信息
$.getJSON('/api/app-info', function(data) {
// 动态更新页面内容
$('#appTitle').text(data.title);
$('#appName').text(data.name);
});
});
</script>
</body>
</html>

运行效果

运行项目后,访问 http://localhost:8080/,首页会通过 jQuery 发送 AJAX 请求,获取后端的应用配置信息,并将这些数据动态地加载到页面中。在网络正常的情况下,页面初次加载时会显示“加载中...”的占位内容,随后 AJAX 请求返回的数据会替换掉占位符,展示出真实的应用名称和标题。后端控制器返回的数据接口可以轻松扩展,前端页面可以根据需要进行相应的数据处理与展示,整个数据传输过程简单明了,代码结构也非常清晰易维护。

总结

在实际开发中,@ControllerAdvice 提供了强大的全局控制能力,使得我们可以在全局范围内进行异常处理、数据绑定等操作。通过 @ModelAttribute 实现的全局数据绑定,可以有效减少控制器中的重复代码,使得代码更加简洁、可维护。结合 jQuery 的动态加载,我们可以轻松实现前后端的数据交互,使应用具备更高的动态性和响应性。

这种开发方式特别适用于大型应用程序,能够帮助开发团队减少代码冗余,集中处理全局逻辑,使应用具有更好的可扩展性和易维护性。在日常开发中,充分利用 Spring boot 提供的全局控制机制,能够让我们的代码更加优雅。


今天就讲到这里,如果有问题需要咨询,大家可以直接留言或扫下方二维码来知识星球找我,我们会尽力为你解答。


AI资源聚合站已经正式上线,该平台不仅仅是一个AI资源聚合站,更是一个为追求知识深度和广度的人们打造的智慧聚集地。通过访问 AI 资源聚合网站 https://ai-ziyuan.techwisdom.cn/,你将进入一个全方位涵盖人工智能和语言模型领域的宝藏库


作者:路条编程(转载请获本公众号授权,并注明作者与出处)

路条编程
路条编程是一个友好的社区,在这里你可以免费学习编程技能,我们旨在激励想学编程的人尝试新的想法和技术,在最短的时间学习到工作中使用到的技术!
 最新文章