当前位置: 首页 > news >正文

Apache Commons Chain 与 Spring Boot 整合:构建用户注册处理链

文章目录

        • 概述
        • 1. 环境准备
        • 2. 创建自定义上下文
        • 3. 创建命令
          • 验证用户输入
          • 保存用户数据
          • 发送欢迎邮件
        • 4. 构建并执行处理链
        • 5. 使用处理链
        • 6. 运行结果
        • 7. 总结

概述

本文档旨在展示如何在 Spring Boot 应用中使用 Apache Commons Chain 来实现一个用户注册的处理链。我们将通过 ChainBaseContextBase 类来组织和管理多个处理步骤,并结合 Spring 的依赖注入和上下文管理功能,以实现一个灵活且可扩展的解决方案。

1. 环境准备

添加依赖

首先,在 pom.xml 中添加必要的 Maven 依赖,确保项目包含了 Apache Commons Chain 和 Spring Boot 的相关库。

<dependencies><!-- Apache Commons Chain --><dependency><groupId>commons-chain</groupId><artifactId>commons-chain</artifactId><version>1.2</version></dependency><!-- Spring Boot Starter Web (或其他你需要的Spring Boot Starter) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
2. 创建自定义上下文

为了在处理链中的每个命令之间传递和共享状态信息,我们需要创建一个继承自 ContextBase 的自定义上下文类。这个类将包含所有与用户注册相关的属性。

import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ContextBase;public class RegistrationContext extends ContextBase {private String username;private String password;private boolean isValid;private boolean isSaved;private boolean emailSent;// Getters and Setterspublic String getUsername() {return (String) get("username");}public void setUsername(String username) {put("username", username);}public String getPassword() {return (String) get("password");}public void setPassword(String password) {put("password", password);}public boolean isValid() {return (boolean) get("isValid");}public void setValid(boolean valid) {put("isValid", valid);}public boolean isSaved() {return (boolean) get("isSaved");}public void setSaved(boolean saved) {put("isSaved", saved);}public boolean isEmailSent() {return (boolean) get("emailSent");}public void setEmailSent(boolean emailSent) {put("emailSent", emailSent);}
}
3. 创建命令

接下来,为每个处理步骤创建一个实现 Command 接口的命令类。每个命令负责执行特定的任务,并根据需要更新上下文的状态。

验证用户输入
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;public class ValidateUserCommand implements Command {@Overridepublic boolean execute(Context context) throws Exception {RegistrationContext regContext = (RegistrationContext) context;String username = regContext.getUsername();String password = regContext.getPassword();// 简单的验证逻辑if (username != null && !username.isEmpty() && password.length() >= 6) {regContext.setValid(true);System.out.println("User input is valid.");} else {regContext.setValid(false);System.out.println("Invalid user input.");}// 返回 false 继续执行链中的下一个命令return !regContext.isValid();}
}
保存用户数据
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;public class SaveUserDataCommand implements Command {@Overridepublic boolean execute(Context context) throws Exception {RegistrationContext regContext = (RegistrationContext) context;if (regContext.isValid()) {// 模拟保存用户数据到数据库System.out.println("Saving user data to database...");regContext.setSaved(true);}// 返回 false 继续执行链中的下一个命令return !regContext.isSaved();}
}
发送欢迎邮件
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;public class SendWelcomeEmailCommand implements Command {@Overridepublic boolean execute(Context context) throws Exception {RegistrationContext regContext = (RegistrationContext) context;if (regContext.isSaved()) {// 模拟发送欢迎邮件System.out.println("Sending welcome email to " + regContext.getUsername() + "...");regContext.setEmailSent(true);}// 返回 false 表示链已经完成return !regContext.isEmailSent();}
}
4. 构建并执行处理链

我们将这些命令组合成一个处理链,并在 Spring Boot 应用中配置和执行它。可以使用 @Configuration 类来定义处理链,并通过 @Bean 注解将其注册为 Spring Bean。

import org.apache.commons.chain.Chain;
import org.apache.commons.chain.impl.ChainBase;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RegistrationChainConfig {@Beanpublic Chain registrationChain() {Chain chain = new ChainBase();chain.addCommand(new ValidateUserCommand());chain.addCommand(new SaveUserDataCommand());chain.addCommand(new SendWelcomeEmailCommand());return chain;}
}
5. 使用处理链

最后,我们可以在控制器或服务层中使用这个处理链来处理用户注册请求。这里以控制器为例:

import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ContextBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class RegistrationController {@Autowiredprivate Chain registrationChain;@PostMapping("/register")public String register(@RequestBody RegistrationRequest request) {// 创建上下文并设置初始数据Context context = new RegistrationContext();((RegistrationContext) context).setUsername(request.getUsername());((RegistrationContext) context).setPassword(request.getPassword());try {// 执行处理链registrationChain.execute(context);// 输出最终状态System.out.println("Registration process completed.");System.out.println("Is valid: " + ((RegistrationContext) context).isValid());System.out.println("Is saved: " + ((RegistrationContext) context).isSaved());System.out.println("Email sent: " + ((RegistrationContext) context).isEmailSent());return "Registration successful!";} catch (Exception e) {e.printStackTrace();return "Registration failed.";}}// 请求体类public static class RegistrationRequest {private String username;private String password;// Getters and Setterspublic String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}
}
6. 运行结果

当你向 /register 端点发送 POST 请求时,例如使用 Postman 或 cURL:

curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"username": "john_doe", "password": "securePassword123"}'

你应该会看到如下输出:

User input is valid.
Saving user data to database...
Sending welcome email to john_doe...
Registration process completed.
Is valid: true
Is saved: true
Email sent: true

并且返回响应:

"Registration successful!"
7. 总结

通过本示例,我们展示了如何使用 Apache Commons Chain 和 Spring Boot 来构建一个灵活且可扩展的用户注册处理链。你可以根据实际需求扩展这个示例,例如添加更多的验证规则、数据库交互逻辑或更复杂的邮件发送机制。Apache Commons Chain 提供了一个强大的框架,可以帮助你组织和管理复杂的业务逻辑,而 Spring Boot 则简化了应用程序的开发和部署过程。

相关文章:

Apache Commons Chain 与 Spring Boot 整合:构建用户注册处理链

文章目录 概述1. 环境准备2. 创建自定义上下文3. 创建命令验证用户输入保存用户数据发送欢迎邮件 4. 构建并执行处理链5. 使用处理链6. 运行结果7. 总结 概述 本文档旨在展示如何在 Spring Boot 应用中使用 Apache Commons Chain 来实现一个用户注册的处理链。我们将通过 Chai…...

一、测试工具LoadRunner Professional脚本编写-录制前设置

设置基于URL的脚本 原因:基于HTML的脚本会导致login接口不能正确录制 设置UTF-8 原因:不勾选此项会导致脚本中文变为乱码...

React Native 组件详解之SectionList、StatusBar、Switch、Text 、 TextInput

在本文中&#xff0c;我们将详细介绍 React Native 中的五个常用组件&#xff1a;SectionList、StatusBar、Switch、Text 和 TextInput。每个组件都有其独特的用途和特性&#xff0c;我们将通过示例代码和 API 说明来帮助你更好地理解和使用它们。 SectionList SectionList 是…...

阿里云:aliyun-cli和ali-instance-cli

概念&#xff1a; 这篇文章只是来澄清一下这俩“cli"之间的区别和联系&#xff1a; aliyun cli 和 ali-instance-cli 都是阿里云提供的命令行工具&#xff0c;但它们的功能和使用场景有所不同。 1. aliyun cli 是一个通用的阿里云命令行接口工具&#xff0c;它允许用户…...

Linux 远程连接服务

远程连接服务器简介 什么是远程连接服务器 远程连接服务器通过文字或图形接口方式来远程登录系统&#xff0c;让你在远程终端前登录linux主机以取得可操 作主机接口&#xff08;shell&#xff09;&#xff0c;而登录后的操作感觉就像是坐在系统前面一样。 远程连接服务器的功…...

Docker 安装和使用

#Docker 安装和使用 文章目录 1. 安装2. 干掉讨厌的 sudo3. 使用镜像源3.1. 使用 upstart 的系统3.2. 使用 systemd 的系统 4. 基本使用4.1. 容器操作4.2. 镜像操作 5. 网络模式说明5.1. bridge 模式5.2. host 模式5.3. container 模式5.4. none 模式 6. 查看 Docker run 启动参…...

web基础和http协议 附:nginx服务的安装

web基础和http协议: https://www.baidu.com/ URL https:// 协议 http:// www.baidu.com/ 域名 web介绍: DNS和域名 DNS解析的方式: 1、运营商 2、/etc/hosts 人工配置的域名和ip地址之间的映射关系 3、/etc/resolv.conf dns服务器的ip地址 bind,内网解析域名和ip地址…...

springboot利用easypoi实现简单导出Excel

vue springboot利用easypoi实现简单导出 前言一、easypoi是什么&#xff1f;二、使用步骤 1.传送门2.前端vue3.后端springboot 3.1编写实体类&#xff08;我这里是dto,也一样&#xff09;3.2控制层结尾 前言 今天玩了一下springboot利用easypoi实现excel的导出&#xff0c;以前…...

【前端新手小白】学习Javascript的【开源好项目】推荐

目录 前言 1 项目介绍 1.1 时间日期类 1.2 网页store类 1.3 事件类 1.4 Number类 1.5 String类 1.6 正则验证类 1.7 ajax类 1.8 data数据类 1.9 browser浏览器类 2 学习js-tool-big-box开源项目时有哪些收获 2.1 你可以这样做 2.2 如果你需要使用本项目 2.3 你…...

CentOS7虚拟机 网络适配器 NAT模式和桥接模式区别

一、环境介绍 宿主机&#xff1a;Windows电脑 虚拟机&#xff1a;VMware下的CentOS7 局域网&#xff1a;路由器下的各真实主机组成的网络 内部局域网&#xff1a;宿主机构建的一个内部网路 二、NAT和桥接网络链接模式区别 NAT模式&#xff1a;相当于宿主机构建一个内部局域网&a…...

sql删除冗余数据

工作或面试中经常能遇见一种场景题&#xff1a;删除冗余的数据&#xff0c;以下是举例介绍相应的解决办法。 举例&#xff1a; 表结构&#xff1a; 解法1&#xff1a;子查询 获取相同数据中id更小的数据项&#xff0c;再将id不属于其中的数据删除。-- 注意&#xff1a;mysql中…...

STM32-C语言基础知识

C语言基础知识 stdint.h简介 给寄存器某个位赋值 给位6赋值为1流程&#xff1a;先清0&#xff0c;再赋值 带参数的宏定义 建议使用do {…}while(0)来构造宏定义 条件编译 条件编译后面必须跟宏语句&#xff0c;如#if _LED_H 指针使用常见的2大问题 1、未初始化 2、越界使…...

【Point-LIO】基于Ubuntu20.04的ROS1平台的Point-LIO部署Mid-360激光雷达

0、前言 Mid360参数 1、代码拉取 2、代码编译运行 文件结构 编译流程&#xff1a; 1、先编译livox_ros_driver2 2、编译整个工程文件 3、运行launch文件&#xff08;livox_ros_driver2&#xff09; 成功启动&#xff1a; 3、实物运行 看得出来&#xff0c;在rviz…...

02_Node.js模块化

02_Node.js模块化 知识点自测 以下代码运行的结果是多少&#xff1f; const arr [10, 20, 30] const result arr.map(val > val 1).reduce((sum, val) > sum val, 0) console.log(result) A&#xff1a;60 B&#xff1a;63 <details><summary>答案</…...

网络——HTTP与HTTPS三次握手和四次挥手

HTTP协议本身并不直接处理TCP连接的建立和关闭&#xff0c;这些是由底层的TCP协议来完成的。但是&#xff0c;由于HTTP通常运行在TCP之上&#xff0c;因此理解TCP的三次握手&#xff08;用于建立连接&#xff09;和四次挥手&#xff08;用于关闭连接&#xff09;对于理解HTTP通…...

ModelScope-Agent(1): 基于开源大语言模型的可定制Agent系统

目录 简介快速入门 简介 github地址 快速入门 看前两篇&#xff0c;调用千问API和天气API # 选用RolePlay 配置agent from modelscope_agent.agents.role_play import RolePlay # NOQArole_template 你扮演一个天气预报助手&#xff0c;你需要查询相应地区的天气&#x…...

开发知识点-uniCloud

开发知识点-uniCloud 服务空间云函数 cloudfunctions云对象importObjectJSON 格式的文档型数据库Collection unicloud数据的指定表集合 DB SchemaJQL 语法参考资料 服务空间 项目关联空间 云函数 cloudfunctions 云对象importObject JSON 格式的文档型数据库 nosql 非关系…...

Redis——主从复制原理

Redis的主从复制原理是其高可用性和分布式读取能力的重要基础。以下是Redis主从复制原理的详细解释&#xff1a; 一、主从复制的基本概念 Redis的主从复制是一种数据复制和备份的方式&#xff0c;它允许一个主节点&#xff08;Master&#xff09;将其所有的数据同步到一个或多…...

MATLAB数学建模之画图汇总

MATLAB是一种强大的数学软件&#xff0c;广泛应用于工程计算、控制设计、信号处理等领域。在数学建模中&#xff0c;MATLAB的绘图功能可以帮助我们直观地展示数据和模型结果。 1. 二维数据曲线图 1.1 绘制二维曲线的基本函数 plot函数用于绘制二维平面上的线性坐标曲线图&am…...

Milvus attu - docker 使用 及 版本兼容

文章目录 版本查看attu 和 milvus 的兼容性Docker 加载attu docker 合并到 Milvus文件管理使用 docker compose 挂在 Milvus,登录 attu 出现报错: Error: Failed to connect to Milvus: Error: 1 CANCELLED: Call cancelled 于是检查兼容问题 版本查看 Milvus 版本发布: htt…...

如何用WeChatExporter轻松备份和恢复微信聊天记录:Mac用户终极指南

如何用WeChatExporter轻松备份和恢复微信聊天记录&#xff1a;Mac用户终极指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾因误删重要微信聊天记录而懊恼不已…...

给你的Alienware设备一次真正的解放:轻量级控制工具完全指南

给你的Alienware设备一次真正的解放&#xff1a;轻量级控制工具完全指南 【免费下载链接】alienfx-tools Alienware systems lights, fans, and power control tools and apps 项目地址: https://gitcode.com/gh_mirrors/al/alienfx-tools 你是否曾经为Alienware Comman…...

DLSS Swapper终极指南:如何免费智能管理游戏DLSS文件,提升游戏性能

DLSS Swapper终极指南&#xff1a;如何免费智能管理游戏DLSS文件&#xff0c;提升游戏性能 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 你是否厌倦了每次游戏更新后手动替换DLSS文件的繁琐操作&#xff1f;你是否希…...

实战指南:AI调用成本降71%——利用“推理路由”告别大模型胡乱开销

大多数 AI 应用在刚开始时&#xff0c;都会在代码中硬编码一个模型。对于原型开发来说&#xff0c;这运行得很好&#xff0c;但一旦单个端点需要处理多个复杂的任务类别&#xff0c;这种模式就会分崩崩离析。分类、紧急程度评分、面向客户的草稿以及长篇总结&#xff0c;这些任…...

手把手复现:用GCC编译选项关闭栈保护,一步步演示缓冲区溢出攻击(附完整代码)

从零构建缓冲区溢出攻击实验&#xff1a;GCC编译选项与漏洞利用实战指南 缓冲区溢出攻击作为系统安全领域的经典课题&#xff0c;至今仍在各类CTF竞赛和实际渗透测试中频繁出现。对于刚接触底层安全的研究者而言&#xff0c;亲手复现一次完整的溢出攻击过程&#xff0c;远比阅读…...

告别轮询!手把手教你用S32K3的FlexCAN Enhanced FIFO+DMA实现高效CAN FD数据接收

告别轮询&#xff01;手把手教你用S32K3的FlexCAN Enhanced FIFODMA实现高效CAN FD数据接收 在汽车电子和工业控制领域&#xff0c;CAN FD总线的高负载场景对MCU的实时性提出了严苛挑战。当波特率飙升至5Mbps、单帧数据扩展到64字节时&#xff0c;传统的中断接收模式会让CPU陷入…...

AirUI全流程可视化开发平台:从设计稿到代码的范式革命

1. 项目概述&#xff1a;从“手写”到“拖拽”的范式转变“告别手写UI代码”&#xff0c;这大概是每个前端开发者在面对复杂页面和频繁需求变更时&#xff0c;内心最真实的呐喊。我入行十几年&#xff0c;从手写HTML、CSS&#xff0c;到使用jQuery&#xff0c;再到拥抱React、V…...

VCSA底层网络配置实战:从IP修改到SSH登录的运维指南

1. 环境准备与基础概念 刚接触VMware vCenter Server Appliance&#xff08;VCSA&#xff09;的朋友可能会觉得底层配置有点神秘。其实就像给新买的智能手机设置Wi-Fi一样&#xff0c;我们需要根据实际网络环境调整它的"网络身份"。VCSA本质上是个预配置的Linux虚拟机…...

Next.js Monorepo包管理:使用Yarn Workspace的10个最佳实践指南

Next.js Monorepo包管理&#xff1a;使用Yarn Workspace的10个最佳实践指南 【免费下载链接】nextjs-monorepo-example Collection of monorepo tips & tricks 项目地址: https://gitcode.com/gh_mirrors/ne/nextjs-monorepo-example 在现代前端开发中&#xff0c;…...

ETime:高效推动你的时间

我做了一个开源时间工作台&#xff1a;ETime 如果你也试过很多时间管理工具&#xff0c;可能会遇到同一种疲惫&#xff1a;记录本身变成了另一件需要坚持的事。 ETime 想解决的不是“怎样把每一分钟都管起来”&#xff0c;而是更朴素的一件事&#xff1a;让开始更轻&#xff…...