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

# 系列文3:前后端彻底解耦!统一入参解析,前端只发JSON,后端随意

系列文3前后端彻底解耦统一入参解析前端只发JSON后端随意非科班野生程序员深耕政务信息化20年这套自研Java Web框架支撑过省级新农保、全国跨省医保结算等核心民生系统18年稳定运行至今。本系列拆解10个核心架构决策全是政务场景踩坑后的实用解法不求优雅但求落地愿同赛道朋友少走弯路也欢迎懂行大佬轻拍指正。最后感谢豆包、智谱、OpenCode决策是我做的代码是我搓的文字是他们总结的。背景前端只有一种通信方式POST JSON。但后端方法签名各不相同——有的要DataCenter有的要HttpServletRequest有的要自定义Dao对象有的要ListDao。能不能让框架根据方法签名自动把 JSON 转换成对应的参数类型比如// 方法1要 DataCenter requestpublicDataCentersave(DataCenterdc,HttpServletRequestreq){...}// 方法2要一个 UserDao 对象publicvoidupdate(UserDaouser){...}// 方法3要一个 ListpublicvoidbatchSave(ListUserDaousers){...}前端不管后端方法签名是什么统一 POST JSON 就行。框架根据方法的参数类型列表自动做类型转换。我的方案在route.java里写了一个praserInParameter()方法根据方法签名自动做参数转换。下面是完整的真实源码praserInParameter() 方法publicstaticObject[]praserInParameter(HttpServletRequestrequest,HttpServletResponseresponse,MethodMapmothodmap)throwsTypeException,IOException{Object[]paramValuesnull;Stringdc;intparameterCountmothodmap.getParametertypeList().size();booleanisreadfalse;if(parameterCount0){paramValuesnewObject[parameterCount];for(inti0;iparameterCount;i){Objecttempnull;SuppressWarnings(rawtypes)Classclsmothodmap.getParametertypeList().get(i);if(clsHttpServletRequest.class){temprequest;}elseif(clsHttpServletResponse.class){tempresponse;}elseif(clsHashMap.class){tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(request);}elseif(clsList.class){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc,mothodmap.getParameterGenerictList().get(i));}elseif(clsnewDataStore.class){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc,mothodmap.getParameterNameList().get(i),mothodmap.getParameterGenerictList().get(i));}else{if(clsDataCenter.class){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc);}elseif(cls.getName().startsWith(com.browise)){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc,cls);}else{temprequest.getParameter(mothodmap.getParameterNameList().get(i));tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(temp);}}paramValues[i]temp;}}returnparamValues;}逻辑拆解这段代码的核心就是遍历方法的参数类型列表对每个参数做不同的处理1. HttpServletRequest / HttpServletResponse直接透传不转换if(clsHttpServletRequest.class){temprequest;}elseif(clsHttpServletResponse.class){tempresponse;}方法里需要 request/response 的直接给你。2. HashMap文件上传elseif(clsHashMap.class){tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(request);}如果参数类型是 HashMap走文件上传的处理逻辑。3. List 类型elseif(clsList.class){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc,mothodmap.getParameterGenerictList().get(i));}List 类型比较特殊——需要知道泛型类型List 里装的是什么所以额外传了parameterGenerictList。泛型信息是在BeanFactory启动时通过getMethodGenericInfo()方法解析的。4. newDataStore 类型elseif(clsnewDataStore.class){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc,mothodmap.getParameterNameList().get(i),mothodmap.getParameterGenerictList().get(i));}这是框架特有的数据结构需要参数名和泛型信息来定位 JSON 中的对应数据块。5. DataCenter 类型if(clsDataCenter.class){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc);}DataCenter是框架的核心数据结构相当于一个增强版的 Map。JSON 反序列化成 DataCenter框架自动处理。6. com.browise 包下的自定义 Daoelseif(cls.getName().startsWith(com.browise)){if(!isread){dcreadDc(request);isreadtrue;}tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(dc,cls);}如果参数是自定义的 Dao 类如 UserDao、OrderDao框架会把 JSON 自动反序列化成对应的 Dao 对象。业务代码直接拿到就是 Java 对象不需要手动解析。7. 普通类型String、int等else{temprequest.getParameter(mothodmap.getParameterNameList().get(i));tempTypeHandlerFactory.newInstance().getTypeHandler(cls).parse(temp);}普通类型从 URL 参数里取值然后通过TypeHandlerFactory做类型转换String→int、String→Date 等。这里的parameterNameList就是系列文5 ASM 读取到的参数名。isread 标志注意一个细节isread标志。因为readDc(request)只能调用一次request 的输入流只能读一次所以用一个布尔变量确保只读一次 JSON后面需要的地方复用dc变量。效果前端永远只管发 JSON后端方法签名随意定义// 方式1通用数据容器 requestresponseMapping(key/save)publicDataCentersave(DataCenterdc,HttpServletRequestreq){...}// 方式2自动反序列化为 DaoresponseMapping(key/update)publicvoidupdate(UserDaouser){...}// 方式3支持泛型列表responseMapping(key/batchSave)publicvoidbatchSave(ListUserDaousers){...}不管方法要什么类型的参数框架自动根据签名做转换。前端完全不需要知道后端方法签名是什么。为什么这样做在这个决策之前每个业务方法都要自己解析参数——从 request 里取值、类型转换、拼装对象。这些重复代码占了每个方法的前几行而且容易出错。有了praserInParameter()之后参数解析变成了框架的事。业务方法直接拿到想要的类型只关注业务逻辑。决策原则前端不关心后端方法签名后端不关心数据是怎么来的。前后端彻底解耦。这个原则也贯穿了整个框架的设计——框架做中间的翻译层前端和后端各自用自己最舒服的方式工作。你觉得前后端参数自动转换这种方式怎么样有没有什么潜在的问题欢迎评论区讨论。系列导航- 上一篇[系列文2新老代码共存的终极解法——注解路由参数路由平滑迁移]- 下一篇[系列文4轻量AOP落地CGLIB代理责任链搞定事务日志监控]作者许彰午| 非科班野生程序员深耕政务信息化20年标签#Java #参数解析 #前后端解耦 #JSON #反射 #类型转换 #政务信息化 #技术复盘

相关文章:

# 系列文3:前后端彻底解耦!统一入参解析,前端只发JSON,后端随意

系列文3:前后端彻底解耦!统一入参解析,前端只发JSON,后端随意 非科班野生程序员,深耕政务信息化20年,这套自研Java Web框架支撑过省级新农保、全国跨省医保结算等核心民生系统,18年稳定运行至今…...

Swoole 5.0适配踩坑实录,深度解析协程生命周期变更、内存管理新规与RPC协议不兼容问题

第一章:Swoole 5.0升级适配全景概览Swoole 5.0 是一次面向现代化 PHP 协程生态的重大演进,彻底移除对传统同步阻塞 API 的兼容包袱,全面拥抱协程原生化设计。其核心变化涵盖事件循环重构、协程调度器强化、HTTP/Server 接口标准化&#xff0c…...

VSCode下载与配置Starry Night Art Gallery开发环境

VSCode下载与配置Starry Night Art Gallery开发环境 如果你对“Starry Night Art Gallery”这个项目感兴趣,想动手参与开发或者自己搭建一个类似的数字艺术画廊,那么第一步就是准备好趁手的开发工具。Visual Studio Code(简称VSCode&#xf…...

手把手教你用Phi-4-mini-reasoning搭建智能解题助手:从部署到实战

手把手教你用Phi-4-mini-reasoning搭建智能解题助手:从部署到实战 1. 项目背景与价值 数学解题一直是学习和教学中的关键环节,但传统方式存在效率低下、资源有限等问题。Phi-4-mini-reasoning作为专为推理任务优化的轻量级模型,为解决这些问…...

第六章:异步访问的同步:6.3.1 dma_resv_usage 层级机制详解

1. 概述 dma_resv(DMA reservation object)是 Linux 内核中管理 GPU buffer 同步的核心机制。每个 dma_resv 对象维护一组 dma_fence,用于追踪对该 buffer 的各种操作。 enum dma_resv_usage 定义了 fence 的用途级别,控制"谁…...

C语言调用MiniCPM-V-2_6推理引擎:高性能嵌入式AI接口开发指南

C语言调用MiniCPM-V-2_6推理引擎:高性能嵌入式AI接口开发指南 如果你是一名C语言开发者,或者正在为嵌入式设备寻找一个既强大又高效的视觉语言模型,那么你来对地方了。今天我们要聊的,是如何用最纯粹的C语言,去直接调…...

YOLOv12官版镜像实战:手把手教你验证COCO数据集,小白也能轻松上手

YOLOv12官版镜像实战:手把手教你验证COCO数据集,小白也能轻松上手 1. 环境准备与快速部署 1.1 镜像环境概览 YOLOv12官版镜像已经预装了所有必要的运行环境,开箱即用。主要配置包括: Python 3.11环境PyTorch 2.5深度学习框架C…...

【THM-题目答案】:Privilege Escalation-Linux Privilege Escalation-Privilege Escalation:PATH

1. 你有写权限的文件夹是什么? What is the odd folder you have write access for?/home/murdoch【思路】:find / -writable 2>/dev/null | cut -d "/" -f 2,3 | grep -v proc | sort -u2. 利用$PATH漏洞读取flag6.txt文件的内容。 Explo…...

ACE-Step应用场景解析:如何为视频快速生成背景音乐?

ACE-Step应用场景解析:如何为视频快速生成背景音乐? 1. 引言:视频创作者的背景音乐痛点 在视频创作过程中,背景音乐的选择往往成为最耗时的环节之一。专业音乐授权费用高昂,免费音乐库又难以找到完全匹配的内容&…...

华为OD机试真题 新系统2026-04-01 C++实现【空间占用计算】

目录 题目 思路 Code 题目 员工A的磁盘空间经常被耗尽,他需要找到占用空间最大的目录或文件,然后决定如何清理文件释放空间。给定某一目录,请编写程序帮助他统计该目录内一级子目录和文件的占用空间,并返回目标目录一级子项(文件或子目录)中占用空间最大的项。 规则说明…...

IndexTTS2 V23问题排查:端口冲突、模型下载慢?常见问题一键解决

IndexTTS2 V23问题排查:端口冲突、模型下载慢?常见问题一键解决 1. 快速入门:IndexTTS2 V23简介 IndexTTS2 V23是由开发者"科哥"推出的最新开源文本转语音(TTS)系统,相比前代版本,它在情感控制和语音自然度…...

Qwen3-14B-Int4-AWQ实战:利用VLOOKUP函数思想实现跨数据源信息智能关联

Qwen3-14B-Int4-AWQ实战:利用VLOOKUP函数思想实现跨数据源信息智能关联 1. 引言:当Excel遇到大数据 "小王,帮我把这两个表格的数据匹配一下。"这样的需求在数据分析工作中再常见不过了。在Excel里,我们通常会使用VLOO…...

数据库安全与运维管控(二):从“共享账号”到本地账密泄露分析

在日常的研发联调和生产排障中,开发人员不可避免地需要连接数据库来核对数据或验证逻辑。目前绝大多数企业的做法依然是:DBA 在底层数据库中执行 GRANT 命令,创建一个只读账号(如 dev_readonly),然后将 IP …...

基于影墨·今颜的Java面试题智能生成与解析系统

基于影墨今颜的Java面试题智能生成与解析系统 面试,对于技术人来说,既是展示能力的舞台,也是一场需要精心准备的“考试”。无论是面试官绞尽脑汁设计能考察真实水平的题目,还是求职者海量刷题却不得要领,传统的面试准…...

Janus-Pro-7B集成Dify实战:构建企业级AI应用工作流

Janus-Pro-7B集成Dify实战:构建企业级AI应用工作流 最近和几个做企业服务的朋友聊天,他们都在头疼一件事:公司里各种业务场景都想用上AI,比如自动审核用户上传的图片、根据商品图生成营销文案,但真要动手做&#xff0…...

大模型学习第8天--python基础(数据结构:列表字典元组)

2026.04.08周二第四部分数据结构:列表list 字典dict 元组tuple 已看完 还剩集合set明天看#列表——增 # stu [] #空列表 # stu ["小明", 18, True, "boys"] # teacher [张老师, 赵老师, 徐老师] # school [teacher, stu, 工作人员, 100] …...

nanobot惊艳效果展示:用‘生成一份Python爬虫获取CSDN文章标题’指令执行结果

nanobot惊艳效果展示:用‘生成一份Python爬虫获取CSDN文章标题’指令执行结果 今天,我想和大家分享一个让我眼前一亮的AI助手体验。最近,我在一个预置了nanobot的镜像环境中,尝试了一个非常具体的指令:“生成一份Pyth…...

Kandinsky-5.0-I2V-Lite-5s本地化部署精讲:JDK环境配置与Docker封装

Kandinsky-5.0-I2V-Lite-5s本地化部署精讲:JDK环境配置与Docker封装 1. 开篇:为什么选择本地化部署 如果你正在寻找一个高效的图像转视频解决方案,Kandinsky-5.0-I2V-Lite-5s绝对值得考虑。这个轻量级模型能够在5秒内完成图像到视频的转换&…...

C++ 入门学习经验 02—— 新手最容易遇到的几个问题以及如何解决

大家好啊!这里是阳阳的博客,一个正在努力学习技术的大学生。上一篇和大家聊了刚接触 C 时的环境搭建、学习路径和心态问题,收到了很多同学的共鸣。所以今天这第二篇,我想继续沿着新手学习时的路线,来和大家聊聊刚学 C …...

.NET源码生成器基于partial范式开发和nuget打包绞

1 安装与初始化 # 全局安装 OpenSpec npm install -g fission-ai/openspeclatest # 在项目目录下初始化 cd /path/to/your-project openspec init 初始化时,OpenSpec 会提示你选择使用的 AI 工具(Claude Code、Cursor、Trae、Qoder 等)。 3 O…...

stock-sdk-mcp 的实践整理郊

一、什么是urllib3? urllib3 是一个用于处理 HTTP 请求和连接池的强大、用户友好的 Python 库。 它可以帮助你: 发送各种 HTTP 请求(GET, POST, PUT, DELETE等)。 管理连接池,提高网络请求效率。 处理重试和重定向。 支…...

你的SSH密钥可能已经过期了档

引言 在现代软件开发中,性能始终是衡量应用质量的重要指标之一。无论是企业级应用、云服务还是桌面程序,性能优化都能显著提升用户体验、降低基础设施成本并增强系统的可扩展性。对于使用 C# 开发的应用程序而言,性能优化涉及多个层面&#x…...

samba服务配置

仅主机 模式下 Samba 完整最简流程(从头到尾)一、虚拟机先改网络(必做)VMware → 虚拟机设置 → 网络适配器选:仅主机模式 (Host-only)二、Linux 自动获取 IP(root)一定得干不然不是同网段后面访…...

知识表示是什么:为什么人工智能离不开知识表示

人工智能不仅要处理数据,还要理解对象、关系、规则和约束。要做到这一点,系统就不能只保存原始记录,而必须把有关内容组织成机器能够处理的形式,这就是知识表示。知识表示并不是人工智能中的附属技术,而是智能系统建立…...

LSTM与GRU的深度解析:门控机制如何解决长时依赖问题?

点击 “AladdinEdu,你的AI学习实践工作坊”,注册即送-H卡级别算力,沉浸式云原生集成开发环境,80G大显存多卡并行,按量弹性计费,教育用户更享超低价。 1. 引言:当序列遇见记忆 自然语言、语音信…...

集合、元素、隶属与包含:知识分类的数学基础

在知识表示与知识图谱中,分类并不是随意进行的。无论是区分类与实例,还是建立上位类与下位类,背后都需要一种更基础的结构来支撑,这就是集合观念。集合、元素、隶属关系、包含关系与相等关系,构成了知识分类最基本的数…...

Android Studio项目集成AI:Phi-4-mini-reasoning 3.8B移动端调用方案

Android Studio项目集成AI:Phi-4-mini-reasoning 3.8B移动端调用方案 1. 移动端AI集成的新机遇 最近在移动开发圈里,AI集成成了热门话题。作为一名长期关注移动端AI落地的开发者,我发现Phi-4-mini-reasoning 3.8B这个轻量级模型特别适合移动…...

OpenClaw多模型切换:Qwen3.5-9B与其他开源模型的协作方案

OpenClaw多模型切换:Qwen3.5-9B与其他开源模型的协作方案 1. 为什么需要多模型协作? 去年我在尝试用AI自动化处理日常工作时,发现一个有趣的现象:当我用同一个大模型处理不同类型的任务时,效果差异非常大。比如用擅长…...

FireRed-OCR Studio实战教程:OCR结果与数据库自动同步脚本

FireRed-OCR Studio实战教程:OCR结果与数据库自动同步脚本 1. 学习目标与场景引入 想象一下这个场景:你是一家公司的行政人员,每天需要处理几十份报销单、合同和发票。你用FireRed-OCR Studio把这些纸质文件扫描成清晰的Markdown文档&#…...

OpenClaw自动化调研:Qwen2.5-VL-7B全网信息收集与分析

OpenClaw自动化调研:Qwen2.5-VL-7B全网信息收集与分析 1. 为什么需要自动化调研工具 作为一个经常需要收集行业动态的技术博主,我过去每天要花2-3小时手动浏览各类网站。直到发现OpenClaw这个能操控浏览器的AI助手,配合Qwen2.5-VL-7B的多模…...