1. 简介
短信(SMS)在现代应用中扮演着重要角色,应用场景非常广泛:✅ 两步验证(2FA)、✅ 实时告警、✅ 聊天机器人、✅ 用户通知等。
本文将带你用 Java 快速实现一个基于 Twilio 的短信发送功能。
市面上支持短信服务的平台不少,比如 Vonage、Plivo、AWS 的 SNS、Zapier 等。但 Twilio 的 SDK 设计简洁,几行代码就能发短信,开发体验非常友好。
2. Twilio 账号配置
要使用 Twilio,首先得注册一个账号。✅ 官方提供免费试用账号,足够用于功能测试。
注册后,你需要做两件事:
- 获取一个 Twilio 提供的虚拟手机号(即发送方号码)
- 将你自己的手机号添加为“已验证号码”(仅试用账号需要)
⚠️ 注意:试用账号只能给已验证的号码发短信,正式账号则无此限制。
Twilio 官方提供了 Java 快速入门指南,跟着走一遍就能完成配置。
3. 初识 TwiML
在写代码前,先了解下 Twilio 的核心通信格式 —— TwiML(Twilio Markup Language)。
TwiML 是基于 XML 的专用标记语言,用来描述通信行为,比如:打电话、发短信、录音等。它的结构非常直观,由“动词”和“名词”组成。
发送短信的 TwiML 示例
<Response>
<Message>
<Body>Sample Twilio SMS</Body>
</Message>
</Response>
拨打电话的 TwiML 示例
<Response>
<Dial>
<Number>415-123-4567</Number>
</Dial>
</Response>
虽然我们不会手动写 TwiML(SDK 会自动处理),但了解其结构有助于理解底层逻辑。
4. 使用 Twilio Java SDK 发送短信
Twilio 提供了功能完整的 Java SDK,无需手动拼 TwiML,直接调 API 即可。
4.1 依赖引入
在 pom.xml
中添加以下依赖:
<dependency>
<groupId>com.twilio.sdk</groupId>
<artifactId>twilio</artifactId>
<version>7.20.0</version>
</dependency>
最新版本可查看 Maven Central
4.2 发送普通短信(SMS)
核心代码如下:
Twilio.init("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "your_auth_token");
Message message = Message.creator(
new PhoneNumber("+12225559999"),
new PhoneNumber("+15017122661"),
"Hello from Twilio via Java!")
.create();
关键点解析:
- ✅
Twilio.init()
:全局初始化,传入你的 Account SID 和 Auth Token(在 Twilio 控制台获取) - ✅
Message.creator()
:构造短信,参数依次是:接收方号码、发送方号码(即 Twilio 分配的号码)、消息内容 - ✅
create()
:执行发送动作,同步阻塞调用
接收方号码必须是已验证号码(试用账号限制)
4.3 发送多媒体短信(MMS)
Twilio 也支持发送图片等多媒体内容,只需额外设置 mediaUrl
:
Twilio.init("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "your_auth_token");
Message message = Message.creator(
new PhoneNumber("+12225559999"),
new PhoneNumber("+15017122661"),
"Check out this image!")
.setMediaUrl(
Promoter.listOfOne(URI.create("https://example.com/image.jpg")))
.create();
⚠️ 注意:
- 接收设备需支持 MMS
- 图片链接必须可公开访问
Promoter.listOfOne()
是 Guava 的工具方法,用于创建单元素列表
5. 短信状态跟踪
发出去不等于收到。Twilio 提供了完整的消息状态追踪机制,帮你判断短信是否成功送达。
5.1 短信状态码说明
状态 | 说明 |
---|---|
queued |
消息已入队,等待发送 |
sending |
正在发送到运营商 |
sent |
运营商已接收 |
delivered |
已送达目标手机(理想状态) |
failed |
发送失败 |
undelivered |
运营商反馈未送达 |
❌ failed
和 undelivered
通常附带错误码,可用于排查问题(如号码无效、运营商拒收等)。
5.2 同步查询状态
通过 Message.reader().read()
获取历史消息状态:
Twilio.init("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "your_auth_token");
ResourceSet messages = Message.reader().read();
for (Message message : messages) {
System.out.println(message.getSid() + " : " + message.getStatus());
}
⚠️ 注意:
- 该方法会发起远程调用,不要频繁使用
- 默认返回所有消息,可通过
.setTo()
、.setDateSent()
等方法过滤
5.3 异步查询状态(推荐)
为避免阻塞主线程,推荐使用异步方式:
Twilio.init("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "your_auth_token");
ListenableFuture<ResourceSet<Message>> future = Message.reader().readAsync();
Futures.addCallback(future, new FutureCallback<ResourceSet<Message>>() {
@Override
public void onSuccess(ResourceSet<Message> messages) {
for (Message msg : messages) {
System.out.println(msg.getSid() + " : " + msg.getStatus());
}
}
@Override
public void onFailure(Throwable t) {
System.out.println("Failed to get message status: " + t.getMessage());
}
}, MoreExecutors.directExecutor());
✅ 使用了 Guava 的 ListenableFuture
,回调在独立线程执行,不影响主流程。
6. 总结
本文演示了如何在 Java 项目中集成 Twilio 实现短信和彩信发送,并介绍了状态追踪的最佳实践。
虽然底层基于 TwiML,但 Twilio 的 Java SDK 封装得非常到位,几行代码就能上线功能,适合快速迭代项目。
完整示例代码已上传至 GitHub:https://github.com/your-repo/twilio-java-demo(mock 地址)