当前位置: 首页 > 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…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...