
如果你在国内做过企业信息化,一定见过这类系统:Tomcat 里跑着一堆 JSP 页面,Action 或 Servlet 里堆着业务逻辑,SQL 拼在 Java 字符串里,界面用 table 或 iframe 布局,改一个字段要在五六个文件之间来回找。它们很多还在稳定运行——稳定得让人不敢动。这类系统的真正困境不是"能不能改",而是"改一次的成本已经高到业务等不起"。本篇把 WebBuilder 与这套经典老架构做一次逐项对比,并给出一条务实的渐进迁移路线。
不吹不黑,JSP + Servlet/JDBC 架构的问题都在工程细节里:
痛点 | 具体表现 |
|---|---|
前后端强耦合在页面模板 | JSP 里混着 Java 循环、HTML 拼接和 JS,一处改动横跨三种语言 |
SQL 分散且手工拼接 | SQL 散落在各 Action 中,字符串拼接为主,注入风险靠人盯 |
无统一组件体系 | 表格、弹窗、树、分页各写各的,同一个"分页条"在系统里有 N 个版本 |
分页/排序/搜索三件套全手写 | 每次新增列表页都要重复一次 |
权限与菜单各自实现 | 菜单表 + 权限表 + 页面内硬编码判断,改权限要改代码 |
文件上传下载方式陈旧 | Servlet 手工解析 multipart,下载头编码在浏览器兼容上翻车 |
无事务与连接池的规范约束 | 连接泄漏是常见故障源,事务边界靠开发者自觉 |
前端无框架、无响应式 | 窄屏不可用,换个分辨率布局就崩 |
部署与热更新 | 改一行要编译 + 重启,验证周期长 |
这些问题的共同点是:每一个单独看都不致命,叠在一起就把交付速度压到地板上。
界面层:不再有模板语言的混编。界面是声明式的 xwl 定义,一个组件一个节点,数据绑定与事件都在配置里:
- cls: Wb.Grid
properties:
cid: grid1
editable: 'true'
multiSelect: 'true'
columnsSortable: 'true'
sorters: code
url: '@xpath + ''/../actions&xaction=dictSelect'''没有 HTML 拼接,没有 JSP 标签,没有前端手写表格。分页、排序、多选、行内编辑都是配置项,这是老架构里每次都要重写的部分。
数据访问层:SQL 从 Java 字符串里搬到服务端脚本,并且有了统一的防注入协议:
sql = 'select a.sid, a.code, a.full_name from wb_staff a where 1=1';
if (Params.search) {
Wb.setLike('search'); // 自动加 % 并转义
sql += ' and (a.full_name like {?search?} or a.code like {?search?})'; // 预编译占位
}
sql += Wb.getOrderSql({ email: 'a.email' }); // 排序白名单,防注入
Wb.sendDict(sql, 'wb,'); // 数据 + 字典一起下发对照老架构:{?search?} 取代了手工拼接,getOrderSql 消灭了"从请求参数直接拼 order by"这个经典的注入入口,sendDict 则让前端连"性别显示成男/女"都不用自己写——字典在服务端翻译好。
连接与事务:老架构里 Connection 的获取、关闭、事务提交都靠模板代码,漏一处就是资源泄漏。WebBuilder 的做法是把连接交给执行上下文:
conn = Wb.getConn(); // 默认库共享连接,执行上下文结束自动归还
conn = Wb.getConn('wb-sqlserver'); // 指定数据源
conn.startTrans(); // 需要事务时显式开始
conn.commit();Wb.sync() 更进一步——它内部自动开事务,三条 SQL 一起成功或一起回滚。老架构里要写十几行的 try/catch/finally/commit/rollback,这里是一个方法调用。
上传下载:老架构里最容易被低估的坑区。WebBuilder 侧上传是 Wb.ajax({ url: xpath + '/actions&xaction=upload', comps: app.uploadCt }),服务端用 new Wb.File(true, 'temp/' + file.name).stream = file.stream 落盘;数据库里的二进制(如照片)则是 Wb.getRow({ blob: true }) 读出流,再 Wb.exportData(row.photo, name) 输出。文件名中文编码、浏览器兼容这些细节由平台处理。
前两节的对照还只是"写法不同",下面四件事是老架构结构上做不到或成本极高的:
1. 组件与字典的复用。 老架构里"新增一个带搜索的列表页"意味着复制一份 JSP、一份 Action、一份 SQL,再改字段名——复制粘贴是这个技术栈的主要生产力。WebBuilder 里同一个 Wb.Grid 配不同的 url 就是不同的列表页,字段定义集中在数据字典,界面无需重复描述。
2. 权限与菜单是平台能力而非项目代码。 平台内置 admin/user、admin/role、admin/perm、admin/dept、admin/log、admin/online-users、admin/task 等模块,权限控制作用于模块与页面的加载环节。老架构里这些都要自研,且往往经不起"换个人来查权限为什么不对"的拷问。
3. 工作流是内置能力。 老架构要做审批流,通常得引第三方引擎再写大量适配层。WebBuilder 里流程用 .flw 文件定义,业务模块只需实现 init(flowId, type, record) 与 afterAction(action, flow) 两个约定:
afterAction(action, flow) {
if (flow.restarting) {
Params.$flow_id = flow.flowId;
Wb.sync({ tableName: 'wb_leave', update: Params, whereFields: 'flow_id' });
} else {
Wb.apply(Params, { sid: Wb.getId(), flow_id: flow.flowId, user_id: flow.handleUser });
Wb.sync({ tableName: 'wb_leave', insert: Params });
}
}4. 服务端也能跑现代 JS。 老架构里做 Excel 导出要引 POI 写一大段 Java;WebBuilder 的服务端脚本里同样是 POI,但代码是几行:
rowx = Wb.getRowx({ sql: 'select * from wb_staff', rs: -1 });
com.wb.office.SheetWriter.createExcel(bos, Wb.toJava(rowx.columns), Wb.toJava(rowx.items), 0, 'Staff List', null);
Wb.exportData(bos.toByteArray(), 'staff.xlsx');对已经在跑的老系统,理性方案是共存与增量替换,而不是重写。经验路线分四步:
第一步:新模块新做。 保留老系统运行,新的业务需求一律用 WebBuilder 开发,部署到同一个 Tomcat(或新端口)。这是最安全也最快见效的一步——通常新需求的交付周期会立刻缩短一半以上。
第二步:老数据直接接。 WebBuilder 通过数据源配置直连老库,不需要数据迁移脚本。老系统的业务表可以原样被新的 xwl 模块读写,因为平台的 SQL 是手写的标准 SQL,对表结构没有侵入性假设(只有 Wb.sync 需要主键字段名,可按约定调整)。
第三步:按使用频次替换老页面。 优先替换那些"用户天天用、改动最频繁"的模块(通常是列表 + 表单)。替换一个模块的成本通常是半天到两天,替换后老页面下线,风险可控。
第四步:切换登录与权限。 最后把入口从老系统迁到平台(用平台用户体系接管登录,权限按角色重配),老系统退化为后台服务或被完全下线。
这条路线的好处是每一步都可回退:第一、二步零风险,第三步是模块级替换(出问题单模块回滚),第四步才涉及全局。整个过程老系统一直在跑,业务不中断。
以"替换一个有搜索、分页、增删改查、导出 Excel、含照片上传的业务模块"为例:
环节 | JSP + Servlet 老架构 | geejing WebBuilder |
|---|---|---|
列表页 | 1 个 JSP + 1 个 Action + 分页工具类 | 1 个 xwl(约 60 行) |
查询与保存 | Action + DAO + SQL 拼接 + 事务模板 | 1 个 actions.xwl(约 60 行) |
导出 Excel | 引 POI,写 Workbook/Sheet/Cell 循环(200+ 行) | 4 行服务端脚本 |
照片上传下载 | multipart 解析 + 存储 + 下载头编码 | 控件配置 + Wb.exportData |
权限控制 | 页面内硬编码判断 + 权限表 | 平台权限模块统一配置 |
人日估算 | 5~8 天 | 1~2 天 |
维度 | JSP + Servlet 老架构 | geejing WebBuilder |
|---|---|---|
界面与逻辑 | 模板混编 | 声明式定义 |
SQL 安全 | 靠开发者自觉 | {?param?} + setLike + 白名单排序 |
连接与事务 | 模板代码全手写 | 上下文托管 / Wb.sync 自动事务 |
权限/流程 | 自研或引第三方 | 内置 |
老系统兼容 | —— | 可直连老库,增量替换 |
单模块替换成本 | 重写 | 1~2 天/模块 |
老系统不该被"推倒重来"绑架,也不该继续用高成本方式续命。增量替换、模块级迁移是这两者之间的第三条路,而 geejing WebBuilder 快速开发平台恰好是这条路线上阻力最小的工具:它不要求你放弃既有的数据库和业务表,却能把每一个新页面和每一次改造的成本压到原来的一个零头。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。