Our web application has SMS (short message service) requirement. Our customer asks to send short message by 三竹簡訊.
Based on its documentation, it provide 8 ways to send short message, and we choose approach 4th.
Here has an diagram to describe 三竹資訊's architecture:
We will use Http Get method to send user name, password, phone number and short message to SmGateway:
And it will return response to your source code:
The status code and its description are as follows:
How-to
The process looks like:
Here has the sample code.
This enumeration contains the status code and its description:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package albert.practice.sms; import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor public enum SmsStatusCodeEnum { STATUS_STAR("*", "系統發生錯誤,請聯絡三竹資訊窗口人員"), STATUS_a("a", "簡訊發送功能暫時停止服務,請稍候再試"), STATUS_b("b", "簡訊發送功能暫時停止服務,請稍候再試"), STATUS_c("c", "請輸入帳號"), STATUS_d("d", "請輸入密碼"), STATUS_e("e", "帳號、密碼錯誤"), STATUS_f("f", "帳號已過期"), STATUS_h("h", "帳號已被停用"), STATUS_k("k", "無效的連線位址"), STATUS_m("m", "必須變更密碼,在變更密碼前,無法使用簡訊發送服務"), STATUS_n("n", "密碼已逾期,在變更密碼前,將無法使用簡訊發送服務"), STATUS_p("p", "沒有權限使用外部Http程式"), STATUS_r("r", "系統暫停服務,請稍後再試"), STATUS_s("s", "帳務處理失敗,無法發送簡訊"), STATUS_t("t", "簡訊已過期"), STATUS_u("u", "簡訊內容不得為空白"), STATUS_v("v", "無效的手機號碼"), STATUS_0("0", "預約傳送中"), STATUS_1("1", "已送達業者"), STATUS_2("2", "已送達業者"), STATUS_3("3", "已送達業者"), STATUS_4("4", "已送達手機"), STATUS_5("5", "內容有錯誤"), STATUS_6("6", "門號有錯誤"), STATUS_7("7", "簡訊已停用"), STATUS_8("8", "逾時無送達"), STATUS_9("9", "預約已取消"); @Getter private String code; @Getter private String description; } |
This utility class is used to send short message:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | package albert.practice.sms; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import com.google.common.collect.Lists; /** * username = 使用者帳號。SmGateway資料庫表格SMUser中需有此使用者,且狀態為啟用。 <br> * password = 使用者密碼 <br> * dstaddr = 受訊方手機號碼 <br> * DestName = 收訊人名稱。若其他系統需要與簡訊資料進行系統整合,此欄位可填入來源系統所產生的Key值,以對應回來源資料庫 <br> * dlvtime = 簡訊預約時間。格式為YYYY-MM-DD HH:NN:SS或YYYYMMDDHHNNSS,或是整數值代表幾秒後傳送。<br> * vldtime = 簡訊有效期限。格式為YYYY-MM-DD HH:NN:SS或YYYYMMDDHHNNSS,或是整數值代表傳送後幾秒後內有效。 <br> * smbody = 簡訊內容。必須為BIG-5編碼,長度70個中文字或是160個英數字。若有換行的需求,請填入ASCII Code 6代表換行。 <br> */ @Slf4j public class SmsUtils { private final static String USER_AGENT = "Mozilla/5.0"; private final String SMS_URL = "http://xxx/SmSendGet.asp?"; private final String USER_NAME = "Test001"; private final String PASSWORD = "TestPwd"; public static void main(String[] args) throws Exception { String phone = "09"; String smBody = "您的驗證碼為○○○○○○,請於收到簡訊10分鐘內完成驗證。"; new SmsUtils().sendSms(phone, smBody); } public void sendSms(String phoneNumber, String body) throws Exception { body = URLEncoder.encode(body, "Big5"); sendGet(phoneNumber, body); } private void sendGet(String phoneNumber, String body) throws IOException { StringBuilder url = new StringBuilder(); url.append(SMS_URL); url.append("username=").append(USER_NAME); url.append("&password=").append(PASSWORD); url.append("&dstaddr=").append(phoneNumber); url.append("&smbody=").append(body); URL obj = null; BufferedReader bufferedReader = null; try { obj = new URL(url.toString()); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); // optional default is GET con.setRequestMethod("GET"); // add request header con.setRequestProperty("User-Agent", USER_AGENT); int responseCode = con.getResponseCode(); log.debug("\nSending 'GET' request to URL : " + url); log.debug("Response Code : " + responseCode); bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine = ""; StringBuffer response = new StringBuffer(); while ((inputLine = bufferedReader.readLine()) != null) { response.append(inputLine); } // print result String responseStr = response.toString(); log.debug(responseStr); int from = responseStr.indexOf("statuscode="); int to = responseStr.indexOf("AccountPoint="); String tmpStr = StringUtils.substring(responseStr, from, to); // 取得status code String statusCode = StringUtils.substring(tmpStr, tmpStr.length() - 1, tmpStr.length()); log.info("statusCode = " + statusCode); // 將status code 轉成 中文訊息 String executionResult = getDescription(statusCode); log.info("executionResult = " + executionResult); List<String> successList = Lists.newArrayList("0", "1", "2", "3", "4"); // 成功的SATUSCODE if (!successList.contains(statusCode)) { throw new RuntimeException(executionResult); } } catch (MalformedURLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { if (bufferedReader != null) { bufferedReader.close(); } } } /** * 將status code 轉成 中文訊息 * * @param statusCode * @return 中文訊息 */ private String getDescription(String statusCode) { String description = ""; for (SmsStatusCodeEnum smsStatusCode : SmsStatusCodeEnum.values()) { if (smsStatusCode.getCode().equals(statusCode)) { description = smsStatusCode.getDescription(); } } return description; } } |