联通短信接口调用全攻略:Java与JS双端实现指南
2025.09.17 15:05浏览量:0简介:本文深入解析Java与JavaScript调用联通短信接口的技术细节,提供从环境配置到异常处理的完整实现方案,助力开发者快速构建短信服务功能。
联通短信接口调用全攻略:Java与JS双端实现指南
一、接口调用前的技术准备
1.1 接口文档解析
联通短信接口采用RESTful架构设计,核心端点包含验证码发送(/sms/send)、状态查询(/sms/query)和余额查询(/account/balance)。接口支持HTTP/HTTPS协议,建议生产环境强制使用HTTPS确保数据传输安全。
参数规范方面,必填字段包括:
appId
:申请的唯一应用标识timestamp
:13位时间戳(毫秒级)sign
:MD5签名(参数按字典序拼接+密钥)mobile
:目标手机号(支持批量发送,逗号分隔)templateId
:模板编号(需提前在控制台申请)
1.2 环境搭建要点
Java环境需配置JDK 1.8+和Maven 3.6+,建议使用Hutool工具包简化HTTP请求。JavaScript端推荐Axios库处理异步请求,配合crypto-js进行签名计算。
开发前需完成:
- 登录联通云市场申请短信服务
- 创建应用获取appId和appKey
- 配置IP白名单(测试环境可设为0.0.0.0/0)
- 申请短信模板并通过审核
二、Java端实现方案
2.1 核心代码实现
import cn.hutool.http.HttpRequest;
import cn.hutool.crypto.digest.MD5;
import java.util.*;
public class LtsSmsClient {
private String appId;
private String appKey;
public LtsSmsClient(String appId, String appKey) {
this.appId = appId;
this.appKey = appKey;
}
public boolean sendSms(String mobile, String templateId, Map<String, String> params) {
String url = "https://api.106msg.cn/sms/send";
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("appId", appId);
paramMap.put("mobile", mobile);
paramMap.put("templateId", templateId);
paramMap.put("params", params);
paramMap.put("timestamp", System.currentTimeMillis());
// 生成签名
String signStr = appId + mobile + templateId +
params.toString() + System.currentTimeMillis() + appKey;
String sign = MD5.create().digestHex(signStr);
paramMap.put("sign", sign);
try {
String response = HttpRequest.post(url)
.form(paramMap)
.timeout(5000)
.execute()
.body();
// 解析JSON响应(示例省略)
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
2.2 高级功能实现
异步发送优化:使用CompletableFuture实现并发控制
public CompletableFuture<Boolean> asyncSend(String mobile, String templateId) {
return CompletableFuture.supplyAsync(() -> sendSms(mobile, templateId, new HashMap<>()));
}
重试机制:指数退避算法实现
public boolean sendWithRetry(String mobile, int maxRetry) {
int retry = 0;
while (retry < maxRetry) {
if (sendSms(mobile, "TEMPLATE_001", new HashMap<>())) {
return true;
}
retry++;
try {
Thread.sleep((long) Math.pow(2, retry) * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return false;
}
三、JavaScript端实现方案
3.1 浏览器端实现
const crypto = require('crypto-js');
class LtsSmsClient {
constructor(appId, appKey) {
this.appId = appId;
this.appKey = appKey;
}
async sendSms(mobile, templateId, params = {}) {
const timestamp = Date.now();
const signStr = `${this.appId}${mobile}${templateId}${JSON.stringify(params)}${timestamp}${this.appKey}`;
const sign = crypto.MD5(signStr).toString();
const response = await axios.post('https://api.106msg.cn/sms/send', {
appId: this.appId,
mobile,
templateId,
params,
timestamp,
sign
}, {
timeout: 5000
});
return response.data;
}
}
// 使用示例
const client = new LtsSmsClient('APP_123', 'SECRET_KEY');
client.sendSms('13800138000', 'TEMPLATE_001')
.then(console.log)
.catch(console.error);
3.2 Node.js服务端优化
连接池管理:使用axios-retry实现自动重试
const axios = require('axios').create({
maxContentLength: Infinity,
maxBodyLength: Infinity,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000
});
批量发送实现:
async function batchSend(mobiles, templateId) {
const chunks = []; // 分块处理(每批100个号码)
const results = [];
for (let i = 0; i < mobiles.length; i += 100) {
const chunk = mobiles.slice(i, i + 100);
const mobileStr = chunk.join(',');
const response = await client.sendSms(mobileStr, templateId);
results.push(response);
}
return results;
}
四、常见问题解决方案
4.1 签名验证失败
- 检查参数拼接顺序是否严格按字典序
- 确认appKey未泄露且未过期
- 时间戳偏差不超过5分钟
4.2 频率限制处理
接口默认限制:
- 单IP:50次/秒
- 单账号:200次/秒
- 单号码:5次/分钟
解决方案:
// 使用Guava RateLimiter实现限流
private final RateLimiter rateLimiter = RateLimiter.create(10.0); // 每秒10次
public boolean rateLimitedSend(String mobile) {
if (rateLimiter.tryAcquire()) {
return sendSms(mobile, "TEMPLATE_001");
}
return false;
}
4.3 异步回调实现
联通支持回调通知,需在控制台配置回调地址:
@RestController
@RequestMapping("/sms/callback")
public class SmsCallbackController {
@PostMapping
public ResponseEntity<String> handleCallback(
@RequestParam String msgId,
@RequestParam String mobile,
@RequestParam String status,
@RequestParam String reportTime,
@RequestHeader("Sign") String sign) {
// 验证签名(示例省略)
// 处理回调逻辑...
return ResponseEntity.ok("SUCCESS");
}
}
五、最佳实践建议
安全防护:
- 接口调用IP限制
- 敏感操作二次验证
- 定期更换appKey
性能优化:
- 批量发送减少请求次数
- 异步处理非实时需求
- 本地缓存模板信息
监控体系:
- 发送成功率统计
- 延迟监控(P99<500ms)
- 失败自动告警
合规要求:
- 用户明确授权
- 退订指令处理
- 数据存储加密
六、调试与测试技巧
- 沙箱环境:使用联通提供的测试账号(前缀170/171号码)
- 日志记录:
```java
// 使用SLF4J记录关键信息
private static final Logger logger = LoggerFactory.getLogger(LtsSmsClient.class);
public void logRequest(String url, Map
logger.info(“SMS Request: URL={}, Params={}”, url,
params.entrySet().stream()
.filter(e -> !e.getKey().equals(“sign”))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
}
3. **模拟测试**:
```javascript
// 使用nock模拟接口响应
const nock = require('nock');
nock('https://api.106msg.cn')
.post('/sms/send')
.reply(200, { code: 0, msgId: 'TEST_123' });
通过以上技术方案的实施,开发者可以构建稳定、高效的联通短信服务系统。实际开发中需根据业务场景选择合适的实现方式,建议先在测试环境完成充分验证后再部署到生产环境。
发表评论
登录后可评论,请前往 登录 或 注册