| 平台 | 優點 | 缺點 | 適合場景 |
| ShareSDK | 價格低、最低充 100 元 | 審核極嚴、需集成 SDK、上架需 20+ 天 | 長期穩定、有 App 上架資質 |
| 萬商雲通訊 (wasun.cn) | 測試帳號秒達、無 SDK 強綁、HTTP API 直連 | 正式模板需備案 | 快速原型、測試、中小專案 |
| 阿里雲/騰訊雲 | 穩定性高、API 規範、控制台完善 | 實名認證、模板審核、價格較高 | 生產環境、大流量 |
學習/原型階段建議用提供測試帳號、HTTP API 直連的平台 (如 wasun.cn),避開 SDK 強綁與漫長審核。
二、HTTP 請求工具類 (原生 HttpURLConnection 版)
public class HttpRequest {
/** GET 請求 */
public static String sendGet(String url, String param) {
StringBuilder result = new StringBuilder();
try (BufferedReader in = new BufferedReader(
new InputStreamReader(new URL(url + "?" + param).openStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = in.readLine()) != null) result.append(line);
} catch (Exception e) { e.printStackTrace(); }
return result.toString();
}
/** POST 請求 (application/x-www-form-urlencoded) */
public static String sendPost(String url, String param) {
StringBuilder result = new StringBuilder();
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
conn.setRequestProperty("User-Agent", "Mozilla/4.0");
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
try (PrintWriter out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8))) {
out.print(param);
out.flush();
}
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = in.readLine()) != null) result.append(line);
}
} catch (Exception e) { e.printStackTrace(); }
return result.toString();
}
}
三、平台官方 HttpClient 3.x 範例 (舊版)
// 需 commons-httpclient-3.1.jar, commons-codec, dom4j
public class SmsSender {
private static final String URL = "https://xxx/webservice/sms.php?method=Submit";
public void send(String mobile, String code) throws Exception {
HttpClient client = new HttpClient();
PostMethod post = new PostMethod(URL);
client.getParams().setContentCharset("UTF-8");
post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
String content = "您的驗證碼是:" + code + "。請勿洩露。";
NameValuePair[] data = {
new NameValuePair("account", "用戶名"),
new NameValuePair("password", "密碼"), // 或 MD5
new NameValuePair("mobile", mobile),
new NameValuePair("content", content)
};
post.setRequestBody(data);
client.executeMethod(post);
String xml = post.getResponseBodyAsString();
// 解析 XML: 2提交成功xxx
Document doc = DocumentHelper.parseText(xml);
Element root = doc.getRootElement();
System.out.println("code=" + root.elementText("code"));
post.releaseConnection();
}
}
四、Servlet 調用示範
@WebServlet("/sendSms")
public class SendSmsServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String mobile = req.getParameter("mobile");
String code = String.valueOf((int)((Math.random()*9+1)*1000)); // 4位數
// 組裝參數 (依平台文檔調整)
String param = "account=xxx&password=yyy&mobile=" + mobile
+ "&content=" + URLEncoder.encode("您的驗證碼:" + code, "UTF-8")
+ "&stime=&sign=&type=pt&extno=";
String result = HttpRequest.sendPost("https://xxx/webservice/sms.php?method=Submit", param);
// 解析 result (XML/JSON/HTML) 判斷是否成功
resp.getWriter().write(result);
}
}
五、關鍵坑點與避坑指南
- 參數名稱以平台 DEMO 為準:官方文檔常過時/錯誤,DEMO 代碼裡的
NameValuePair key 才是標準。
- 內容編碼:
content 必須 URLEncoder.encode(..., "UTF-8"),且平台要求模板格式固定 (如「您的驗證碼是:【變量】」),不可隨意修改。
- 回應格式非標準 JSON:部分平台返回 HTML 片段或純文本,需用正則/Jsoup 解析,而非
JSONObject。
- 同步阻塞風險:HTTP 發送短信屬網路 I/O,建議放入線程池或消息隊列 (RabbitMQ/Kafka) 異步處理,避免阻塞 Servlet 線程。
- 頻率限制:同一手機號/同一 IP 分鐘/小時/天發送上限,需在業務層攔截 (Redis 計數器)。
- 測試號碼白名單:測試階段平台常限制只能發給綁定的測試手機號。
總結
短信驗證碼接入核心在於 參數組裝準確、編碼正確、回應解析健壯、異步非阻塞、頻率限制。學習階段選擇 HTTP API 直連、提供測試帳號的平台;生產環境轉向雲廠商 (阿里/騰訊/華為) 享受高達 99.9% 到達率與完善監控。
- 上一篇文章: Java split 分割字串的邊界陷阱:尾部空欄位被丟棄的原因與三種解決方案</x2Title>
<xTitle>Java split 分割字串的邊界陷阱:尾部空欄位被丟棄的原因與三種解決方案
- 下一篇文章: Java JDBC 連接 MySQL 完整入門:驅動載入、連接池、CRUD 範本與資源管理鐵律
Copyright ©
程式碼之家 All Rights Reserved