logo

联通短信接口集成指南:Java与JS双端实现详解

作者:很酷cat2025.09.25 17:12浏览量:0

简介:本文详细解析Java与JavaScript调用联通短信接口的实现方法,涵盖技术选型、开发流程、安全优化及异常处理,为开发者提供全链路技术指导。

联通短信接口集成指南:Java与JS双端实现详解

一、技术选型与接口特性

联通短信接口采用RESTful API设计,支持HTTP/HTTPS协议,提供验证码发送、营销短信、通知类短信三大核心功能。接口参数包括appId(应用标识)、timestamp(时间戳)、sign(数字签名)等安全验证字段,其中签名算法采用MD5加密,需将参数按字典序拼接后与密钥组合生成。

Java端推荐使用Apache HttpClient 4.5+或OkHttp 3.x实现HTTP请求,JS端可通过axios或原生Fetch API调用。两种技术栈均需处理异步回调与错误重试机制,Java可通过CompletableFuture实现,JS则依赖Promise或async/await语法。

二、Java实现关键步骤

1. 依赖配置

Maven项目需引入以下依赖:

  1. <dependency>
  2. <groupId>org.apache.httpcomponents</groupId>
  3. <artifactId>httpclient</artifactId>
  4. <version>4.5.13</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>commons-codec</groupId>
  8. <artifactId>commons-codec</artifactId>
  9. <version>1.15</version>
  10. </dependency>

2. 签名生成算法

  1. public class SignUtil {
  2. public static String generateSign(Map<String, String> params, String secretKey) {
  3. // 参数按字典序排序
  4. params.entrySet().stream()
  5. .filter(e -> e.getValue() != null)
  6. .sorted(Map.Entry.comparingByKey())
  7. .forEach(e -> params.put(e.getKey(), e.getValue()));
  8. // 拼接签名串
  9. StringBuilder sb = new StringBuilder();
  10. params.forEach((k, v) -> sb.append(k).append("=").append(v).append("&"));
  11. sb.append("key=").append(secretKey);
  12. // MD5加密并转大写
  13. return DigestUtils.md5Hex(sb.toString()).toUpperCase();
  14. }
  15. }

3. 完整请求示例

  1. public class SmsSender {
  2. private static final String URL = "https://api.10010.com/sms/send";
  3. public static boolean sendSms(String phone, String content) throws Exception {
  4. CloseableHttpClient httpClient = HttpClients.createDefault();
  5. HttpPost httpPost = new HttpPost(URL);
  6. // 构建请求参数
  7. Map<String, String> params = new HashMap<>();
  8. params.put("appId", "YOUR_APP_ID");
  9. params.put("timestamp", String.valueOf(System.currentTimeMillis()));
  10. params.put("phone", phone);
  11. params.put("content", content);
  12. params.put("sign", SignUtil.generateSign(params, "YOUR_SECRET_KEY"));
  13. // 设置请求体
  14. List<NameValuePair> nvps = new ArrayList<>();
  15. params.forEach((k, v) -> nvps.add(new BasicNameValuePair(k, v)));
  16. httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
  17. // 执行请求
  18. try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
  19. String result = EntityUtils.toString(response.getEntity());
  20. return "0000".equals(JSON.parseObject(result).getString("code"));
  21. }
  22. }
  23. }

三、JavaScript实现要点

1. 浏览器端实现

  1. async function sendSms(phone, content) {
  2. const params = new URLSearchParams();
  3. params.append('appId', 'YOUR_APP_ID');
  4. params.append('timestamp', Date.now());
  5. params.append('phone', phone);
  6. params.append('content', content);
  7. // 生成签名(需后端提供签名服务或使用WebAssembly)
  8. const sign = await generateSign(params, 'YOUR_SECRET_KEY');
  9. params.append('sign', sign);
  10. try {
  11. const response = await fetch('https://api.10010.com/sms/send', {
  12. method: 'POST',
  13. body: params,
  14. headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
  15. });
  16. const data = await response.json();
  17. return data.code === '0000';
  18. } catch (error) {
  19. console.error('SMS send failed:', error);
  20. return false;
  21. }
  22. }
  23. // 实际项目中建议将签名生成放在服务端
  24. async function generateSign(params, secretKey) {
  25. // 模拟签名生成(实际需实现完整算法)
  26. return 'MOCK_SIGNATURE';
  27. }

2. Node.js服务端实现

  1. const axios = require('axios');
  2. const crypto = require('crypto');
  3. function generateSign(params, secretKey) {
  4. const sortedParams = Object.keys(params)
  5. .filter(key => params[key] !== null)
  6. .sort()
  7. .map(key => `${key}=${params[key]}`)
  8. .join('&');
  9. const signStr = `${sortedParams}&key=${secretKey}`;
  10. return crypto.createHash('md5').update(signStr).digest('hex').toUpperCase();
  11. }
  12. async function sendSms(phone, content) {
  13. const params = {
  14. appId: 'YOUR_APP_ID',
  15. timestamp: Date.now(),
  16. phone,
  17. content
  18. };
  19. params.sign = generateSign(params, 'YOUR_SECRET_KEY');
  20. try {
  21. const response = await axios.post('https://api.10010.com/sms/send',
  22. new URLSearchParams(params),
  23. { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
  24. );
  25. return response.data.code === '0000';
  26. } catch (error) {
  27. console.error('SMS send failed:', error.response?.data || error.message);
  28. return false;
  29. }
  30. }

四、安全优化方案

  1. 密钥管理:采用KMS(密钥管理服务)存储密钥,Java端通过JCEKS密钥库,JS端通过环境变量注入
  2. IP白名单:在联通控制台配置允许访问的服务器IP
  3. 频率限制:实现令牌桶算法控制发送速率,Java可使用Guava RateLimiter
  4. 内容过滤:对短信内容进行敏感词检测,JS端可使用正则表达式预检

五、异常处理机制

1. 错误码对照表

错误码 含义 处理方案
1001 参数缺失 检查必填字段
2003 签名错误 重新生成签名
3005 频率超限 指数退避重试
9999 系统异常 切换备用接口

2. 重试策略实现

  1. // Java重试机制示例
  2. public class RetryUtil {
  3. public static <T> T executeWithRetry(Callable<T> task, int maxRetries, long delayMillis)
  4. throws Exception {
  5. Exception lastException = null;
  6. for (int i = 0; i < maxRetries; i++) {
  7. try {
  8. return task.call();
  9. } catch (Exception e) {
  10. lastException = e;
  11. if (i < maxRetries - 1) {
  12. Thread.sleep(delayMillis * (long) Math.pow(2, i));
  13. }
  14. }
  15. }
  16. throw lastException;
  17. }
  18. }

六、性能优化建议

  1. 连接池配置:Java端配置HttpClient连接池
    1. PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    2. cm.setMaxTotal(200);
    3. cm.setDefaultMaxPerRoute(20);
  2. 异步非阻塞:JS端使用WebSocket长连接替代短连接
  3. 批量发送:联通接口支持批量发送,Java可通过多线程并发处理

七、监控与日志

  1. 调用统计:记录发送成功率、平均耗时等指标
  2. 日志规范:Java使用Log4j2,JS使用winston,记录请求参数(脱敏后)、响应结果
  3. 告警机制:当连续失败超过阈值时触发告警

通过以上技术实现,开发者可构建稳定、高效的联通短信服务系统。实际开发中需根据业务场景调整参数配置,并定期进行压力测试确保系统可靠性。

相关文章推荐

发表评论