Ecology通用短信接口:中间表模式搞定多供应商接入

发布时间:2026/10/16 16:10:27
Ecology通用短信接口:中间表模式搞定多供应商接入
简介Ecology通用短信接口实现是一份面向Ecology平台实施与二次开发人员的技术文档主要解决短信设备供应商众多、逐一集成成本高的问题。方案基于中间表设计Ecology仅将短信内容与接收人写入指定数据库的中间表由设备供应商或客户自行读取发送从而有效降低系统与硬件厂商的耦合。资源包仅38KB内含1个doc文档完整介绍接口原理、配置方法及使用注意点重点说明ecology/WEB-INF/service/sms.xml中各参数含义包括数据库类型、服务器IP、端口、库名、用户名、密码以及自定义插入SQL并给出SqlServer与Oracle两种建表脚本可直接参考落地。文中特别提醒必须使用SqlServer或Oracle数据库且中间表必须包含短信内容和接收人字段。已有436人学习下载适合需要快速为Ecology系统接入短信通知的开发者。1. Ecology短信接口用一张中间表解决多供应商接入难题做过Ecology二次开发的都知道短信接入是个躲不开的环节。不同客户用的短信设备供应商五花八门有的用数据库中间表有的要求HTTP接口还有的只给一个串口设备。如果每来一个供应商就做一次集成开发开发和维护成本完全失控。Ecology通用短信接口的设计思路很直接Ecology只负责把待发送短信写入中间表发送动作交给供应商或客户自己的程序完成。换句话说Ecology不做发送者只做数据的搬运工。这套方案适合谁一类是做Ecology实施的项目顾问需要在不同客户现场快速对接短信网关另一类是客户方IT人员想搞明白短信发送链路是怎么串起来的出了问题能自己排查。方案的技术门槛不高核心就是一个配置文件加一张表但细节不少比如字段映射、序列、触发器、不同数据库的语法差异任何一处没处理好短信就发不出去。下文从接口原理、配置拆解、中间表设计、扩展实现到验收答辩完整过一遍这套通用短信接口的落地过程。数据库只支持SqlServer和Oracle中间表必须有短信内容和接收人两个字段这两个约束决定了整个方案的边界。2. 接口原理与配置设计sms.xml核心参数逐项拆解2.1 中间表模式的工作原理通用短信接口的出发点很简单Ecology通过JDBC直连存放中间表的数据库把短信接收人和短信内容以参数化SQL的方式插入中间表。短信供应商的程序按自己的扫描频率轮询这张表发现新数据就取走并通过短信网关发送发送完成后按自己规则标记状态。整个链路中Ecology只负责一件事——写数据。中间表放在哪个库、表名叫什么、字段有哪些这些都不限定因为插入SQL是配置在文件里的客户表结构怎么设计都能适配。但有两个硬性条件数据库必须是SqlServer或Oracle其他数据库不支持中间表必须有存放短信内容、接收人的字段否则无从写入。实际项目中这个模式最大的优势是解耦。Ecology版本升级、短信供应商更换互不影响。供应商只需要知道中间表结构写个扫描程序就行。我见过不少客户短信发送程序本身就是供应商提供的标准组件他们对接中间表已经轻车熟路。2.2 sms.xml定位与配置项详解配置文件位于ecology/WEB-INF/service/sms.xml这是Ecology短信服务的核心装配文件。打开后看到的完整结构是module idsms version1.0.0 service-point idsmssender interfaceweaver.sms.SmsService invoke-factory construct classweaver.sms.JdbcSmsService set propertytype valuesqlserver/ set propertyhost value192.168.0.204/ set propertyport value1433/ set propertydbname valueecology3802/ set propertyusername valuesa/ set propertypassword value123/ set propertysql valueinsert into OutBox(ReceiverMobileNo,Msg,SendTime,IsChinese,ExpressLevel,Sender) values(?,?,getDate(),1,1,1)/ /construct /invoke-factory /service-point /module这段配置需要关注的参数有七个。type表示中间表所在数据库类型sqlserver就写sqlserver换Oracle就改成oracle。host是中间表所在数据库服务器的IP地址注意这里不一定和Ecology数据库是同一个IP中间表完全可以放在独立的库上。port是数据库端口SqlServer默认1433Oracle默认1521。dbname是中间表所在数据库名username和password是连接数据库的账号密码。最后那个sql参数最关键指定了往中间表插入数据时执行的SQL语句。这里用了两个问号占位符对应短信接收人和短信内容这两个值由Ecology接口运行时动态传入。其他字段比如SendTime、IsChinese、ExpressLevel、Sender都写死为固定值因为发送方不关心这些字段的准确性。2.3 数据库连接参数与weaver.properties的关系这些连接配置和ecology/WEB-INF/prop/weaver.properties中的数据库连接参数格式类似理解了weaver.properties就不难理解这里。区别在于sms.xml里的host、port、dbname、username、password指向的是中间表所在的数据库而weaver.properties配置的是Ecology系统本身的数据库连接。两者可以指向同一个实例但在大型项目中通常是分开的避免短信供应商的扫描程序对Ecology核心库造成额外负载。有一点容易忽略如果客户环境启用了短信服务还需要修改ecology/WEB-INF/prop/weaver_rtx.properties把CurSmsServerrtx这一行注释掉。这个参数指定了当前短信发送设备的类型rtx是即时通讯服务的配置。注释掉之后系统才会走sms.xml中配置的通用短信接口。实际操作中我一般用#号注释掉不是删除方便以后回滚。常见的配置误区是把中间的字段名写成大写或者带引号。在SqlServer中不区分大小写还好在Oracle中如果中间表字段是使用引号创建的小写字段名那SQL里必须带双引号精确匹配否则会报标识符无效的错误。这个细节后面避坑章节会再展开。3. 中间表设计SqlServer与Oracle双库落地实现3.1 SqlServer中间表建表脚本与字段说明中间表结构设计得越简单越好。SqlServer环境下给客户提供的参考建表脚本如下CREATE TABLE outbox ( ID int IDENTITY (1, 1), ExpressLevel int, Sender varchar (50), ReceiverMobileNo varchar (50), Msg varchar (500), SendTime datetime, IsChinese bit )字段含义逐个说。ReceiverMobileNo存放接收人手机号Msg存放短信内容这两个是接口写入时用问号占位符替代的字段。Sender是发送人标识SendTime是发送时间在SQL里通过getDate()函数由数据库自己生成。ExpressLevel表示紧急程度IsChinese标记短信内容是否为中文这两个字段接口传入的固定值是1实际供应商的程序很少依赖这两个字段保留是为了兼容常见短信网关的参数格式。如果需要按主流短信网关的习惯增加ID自增列SQLServer里用IDENTITY(1,1)即可。ID列在很多短信扫描程序里是必读的用于记录哪些短信已经取走、哪些还没处理避免重复发送。如果客户的中间表已有其他表名和字段名那就直接修改sms.xml中的SQL做字段映射就行。3.2 Oracle中间表建表脚本、序列与触发器换成Oracle环境建表脚本就不只是建表了还涉及序列和触发器的配合。完整脚本如下CREATE TABLE OUTBOX ( ID NUMBER not null, EXPRESSLEVEL NUMBER, SENDER VARCHAR2(50), RECEIVERMOBILENO VARCHAR2(50) not null, MSG VARCHAR2(500), SENDTIME DATE not null, ISCHINESE NUMBER not null ); CREATE SEQUENCE OUTBOX_ID_SEQ minvalue 1 maxvalue 999999999 start with 141 increment by 1 cache 20; CREATE OR REPLACE TRIGGER SET_OUTBOX_ID BEFORE INSERT ON OUTBOX FOR EACH ROW DECLARE NEXT_OUTBOX_ID NUMBER; BEGIN SELECT OUTBOX_ID_SEQ.NEXTVAL INTO NEXT_OUTBOX_ID FROM DUAL; :NEW.ID : NEXT_OUTBOX_ID; END;Oracle和SqlServer有几个明显差异。字段类型从int变NUMBERbit变NUMBERdatetime变DATEvarchar变VARCHAR2。最大的差异是ID列的处理SqlServer用IDENTITY自动生成Oracle没有自增列必须用序列加触发器实现。触发器在插入前自动从序列取下一个值赋给ID字段这样INSERT语句里就不需要显式提供ID。有时候客户库里的序列已经存在或者ID生成规则由其他程序控制那就把触发器去掉直接用他们现有的序列。注意这里的start with 141是原方案里的起始值实际部署时应该根据现有数据情况调整比如当前最大ID加1。3.3 两种数据库下sms.xml的SQL差异对应的Oracle版sms.xml配置核心变化有三个地方type改为oracleport改为1521SQL中的时间函数从getDate()改为(select sysdate from dual)。完整配置如下module idsms version1.0.0 service-point idsmssender interfaceweaver.sms.SmsService invoke-factory construct classweaver.sms.JdbcSmsService set propertytype valueoracle/ set propertyhost value192.168.0.204/ set propertyport value1521/ set propertydbname valueweaver1/ set propertyusername valueecology40002/ set propertypassword valueecology/ set propertysql valueinsert into OutBox(ReceiverMobileNo,Msg,SendTime,IsChinese,ExpressLevel,Sender) values(?,?,(select sysdate from dual),1,1,1)/ /construct /invoke-factory /service-point /module写SQL时有个细节SqlServer中getDate()可以直接写Oracle中获取当前时间要用(select sysdate from dual)子查询。另外Oracle的INSERT值里字符串类型字段最好用单引号包裹比如Sender字段写1而数字字段可以不带引号。如果表里的字段是VARCHAR2类型传入时写成1会导致隐式转换大多数情况没问题但遇到字段内容包含非数字字符时就会报错。接口本身对SendTime、IsChinese、ExpressLevel、Sender这些字段其实不关心它们只是用来凑齐SQL的必要字段。如果客户的中间表只有ReceiverMobileNo和Msg两个字段那INSERT语句可以简化成insert into someTable(MobileNo, messageBody) values(?,?)其余的都不需要。4. 接口扩展自定义Java短信服务的实现与部署路径4.1 为什么需要自定义发送实现中间表方案的实时性取决于供应商扫描程序的轮询频率。扫描间隔30秒短信从触发到发出就平均延迟15秒扫描间隔5分钟延迟就是2分半。对审批通知类短信还能忍受但如果客户要做短信验证码、告警通知这类时效性要求高的场景轮询模式就会显得迟钝。如果客户不满意中间表方案Ecology也提供了一条扩展路径自己实现短信发送方法用Java编写部署后Ecology在发送短信时就会调用客户实现。这种方法不走中间表Ecology直接调用客户代码完成发送实时性由客户的实现逻辑决定可以做到同步发送。这种方式适合有Java开发能力的客户。比如客户内部已有成熟的短信网关API封装好之后只需写个适配类对接Ecology的接口规范即可。对于没有开发能力的客户还是用中间表方案更稳妥毕竟只需要SQL层面的配置不需要写代码。4.2 SmsService接口定义与实现类编写自定义实现的核心是Ecology提供的weaver.sms.SmsService接口。接口声明如下public interface SmsService { public boolean sendSMS(String smsId, String number, String msg); }三个参数的含义分别是smsId是短信记录的唯一标识number是接收人手机号msg是短信内容。返回值boolean表示发送是否成功返回true代表发送成功false代表失败。一个最简单的实现类可以这样写public class TestService implements SmsService { public boolean sendSMS(String smsId, String number, String msg) { System.out.println(接受人 number); System.out.println(测试短信 msg); return true; } }实际开发时sendSMS方法内部应该调用短信供应商的HTTP接口或SDK。有的HTTP接口需要对msg做URL编码有的要求number以逗号分隔批量发送还有的需要在msg前追加签名这些都是这个实现类里该干的事。4.3 sms.xml中切换实现类的配置变更部署自定义实现的步骤分两步。第一步把编译好的.class文件放到Ecology的类路径下通常放在WEB-INF/classes目录。第二步修改sms.xml把construct的class属性从weaver.sms.JdbcSmsService改为自定义类名同时删除不再使用的数据库连接参数。修改后的配置如下module idsms version1.0.0 service-point idsmssender interfaceweaver.sms.SmsService invoke-factory construct classTestService /construct /invoke-factory /service-point /module切换后Ecology发送短信时不再操作中间表直接把参数传给TestService的sendSMS方法。这个设计的优点是灵活客户可以从中间表模式平滑切换到自定义模式不需要改动Ecology的其他代码。缺点是需要Java开发能力调试也依赖日志输出不像中间表方案可以用SQL查询直接验证数据是否写入。4.4 两种方案的适用场景对比中间表和自定义实现并不冲突它们是按场景选择的。中间表方案适合短信量可控、实时性要求不高的场景比如流程审批通知、日常消息提醒客户现场没有Java开发人员时优先用这个。自定义实现适合验证码类、告警类短信或者客户已有特定短信网关需要对接的场景前提是客户有Java能力或者愿意请Ecology厂商的開發人員协助。还有一类客户选型是混合的日常通知走中间表方案批量轮询紧急告警走自定义实现同步发送。sms.xml里的service-point只能配置一个class无法同时配置两种所以混合场景通常是在自定义实现里做分发方法内部判断短信类型再决定走中间表还是直接调网关。5. 常见问题与避坑中间表模式最容易翻车的五个点5.1 数据库类型不匹配导致连接失败现象是启动Ecology后发送短信无反应日志报无法连接数据库或驱动类错误。原因通常是sms.xml中type值写错比如实际是Oracle却写成sqlserver或者host和port配置指向了错误的实例。SqlServer的端口默认1433Oracle默认1521如果客户改过监听端口这里必须同步修改。解决方法是先确认中间表数据库的实际类型和端口然后用数据库客户端工具手动测试连接确认后再填进sms.xml。5.2 Oracle建表脚本重复执行报错现象是执行Oracle建表脚本时提示ORA-00955或ORA-04089之类的错误。原因是对接的库里已经有同名表、同名序列或同名触发器或者客户DBA已经手工建好了OUTBOX表。解决方法是先查询已存在的对象比如select count(*) from user_tables where table_nameOUTBOX如果表存在就跳过建表语句只补充表结构里缺少的字段序列和触发器同理。盲目执行脚本会把原有对象破坏造成不可预估的后果。通常的做法是在正式环境操作前先找DBA确认对象的属主和权限。5.3 Oracle大小写敏感导致字段找不到现象是SQL看似没问题但执行时报ORA-00904标识符无效。原因是在Oracle中如果建表时字段名没加双引号字段会以大写形式存储SQL里写小写也没问题因为Oracle默认把没有引号的标识符转为大写。但如果建表脚本里用了双引号创建了小写字段名比如receiverMobileNo那SQL里必须用双引号精确匹配大小写写成receiverMobileNo不带引号就会报错。这也是为什么建表脚本里字段名统一用大写字母的原因。解决方法是检查表字段的定义方式SQL中的字段名和表定义保持完全一致。5.4 短信重复发送现象是同一批短信被发送了多次接收人收到重复信息。原因有两种一是中间表没有ID或唯一标识供应商的扫描程序无法判断记录是否已处理每次轮询都当成新短信二是Ecology发送短信时对同一记录写入了多条比如流程节点配置重复触发了短信操作。解决方法是确保中间表有自增IDSqlServer用IDENTITYOracle用序列加触发器同时在Ecology端核查触发短信的业务规则避免同一个动作被调用多次。血泪经验是重复发送问题通常不在接口层而在触发逻辑层。5.5 中文短信内容乱码现象是短信发送成功但接收人收到的内容是乱码或问号。原因是Ecology写入中间表时编码与数据库字符集不一致或者供应商扫描程序读取时按单字节解析中文内容。解决方法是检查三处编码Ecology数据库连接的字符集参数中间表字段的字符集类型供应商扫描程序的读取编码。SqlServer里varchar是单字节需要把短信内容字段改为nvarchar才能正确存储中文字符Oracle里VARCHAR2默认按数据库字符集存储如果库字符集是AL32UTF8一般没问题。配置里的IsChinese字段也为供应商程序提供了判断中文短信的依据。这个坑比较隐蔽自测时用纯英文短信看不出来一上中文内容就翻车。6. 验收与答辩用一套完整测试案例证明接口可用方案做完只算完成一半另一半是让客户或导师相信真的能用。我一般用一套三层验收法走完整个测试流程。第一层验证配置连通性。修改sms.xml之后重启Ecology服务在系统里触发一条测试短信。如果走中间表方案直接用数据库客户端查询中间表看RECEIVERMOBILENO和MSG字段是否有数据写入。表里有记录说明连接配置和SQL正确是供应商扫描程序的问题表里没记录说明问题在Ecology到中间表这一段重点排查sms.xml参数。第二层验证发送链路完整性。在中间表里手工插入一条测试记录观察供应商的扫描程序是否取走、外网能否收到短信。这一步能区分问题是出在Ecology侧还是供应商侧。如果手工插入的记录能收到短信说明供应商通道正常问题只可能在配置。如果手工插入也收不到就要找供应商排查他们的程序。第三层验证Oracle场景的完整流程。建好表、序列、触发器配置好Oracle版sms.xml重复第一层和第二层的操作。注意测试时短信内容分别用纯数字、纯中文、数字加中文三种确保中文编码没有问题。另外确认ID序列是从当前表最大ID之后开始递增避免主键冲突。答辩时会遇到的问题基本集中在几个点上。为什么不用HTTP接口直连答Ecology面对的是不同短信供应商中间表模式是所有供应商都支持的标准对接方式不需要为每家写适配代码。为什么只支持SqlServer和Oracle答Ecology主流部署环境就是这两个数据库中间表依赖数据库定时任务能力这两个库在这个场景下最稳定。中间表方案的实时性怎么解决答一是调高供应商扫描频率二是对实时性要求高的短信走自定义实现路径写Java类同步发送。还有一道高频题中间表里哪些字段必需只需要接收人号码和短信内容两个字段其他字段是为了兼容常见短信网关的习惯性字段不是接口强制的。这套方案的验收关键卡在两端一端是Ecology写入中间表的数据是否正确一端是供应商发送通道是否通畅。两端分开验证哪一段出问题就缩小到哪一段排查比整体黑匣子式调试高效得多。从那以后我每次做短信接口对接都强制自己先把两端的验证SQL和接口文档写好再动配置。先定义好验收路径再开始实施返工率能降一半。希望帮到你。本文还有配套的精品资源点击获取