使用Java第三方實(shí)現(xiàn)發(fā)送短信功能
一、介紹
在項(xiàng)目開發(fā)中,短信發(fā)送功能在很多地方都用得到,例如:通知短信、驗(yàn)證碼、營銷短信、推廣短信等等,近期阿里云等云服務(wù)商的短信服務(wù)針對個(gè)人用戶不友好(需求企業(yè)資質(zhì)),現(xiàn)在給大家介紹一款的產(chǎn)品:樂訊通,針對個(gè)人用戶較為友好,可以很便捷的進(jìn)行開發(fā)測試。
樂訊通官網(wǎng):http://yun.loktong.com/
二、使用步驟
1. 平臺(tái)注冊
使用手機(jī)號(hào)注冊即可。
注意:注冊成功后,默認(rèn)密碼就是手機(jī)號(hào)。
可在 “系統(tǒng)管理”->"密碼管理"中進(jìn)行密碼的修改 。
2. 短信簽名和短信模板
平時(shí)比較常見的驗(yàn)證碼短信格式為:【碼賽客1024】:注冊驗(yàn)證碼為312562,請勿泄露給他人。
前面括號(hào)中的就是短信簽名,后邊部分就是短信模板,因此可以分析出格式為:【短信簽名】:短信模板。
2.1 設(shè)置簽名
文字短信 -> 短信設(shè)置 -> 簽名管理 -> 添加新的簽名
2.2 設(shè)置模板
文字短信 -> 短信設(shè)置 -> 簽名管理 -> 添加新的模板
模板設(shè)置需要注意的是,模板中使用{}作為占位符,例如:
【短信簽名】:注冊驗(yàn)證碼為{s6},請勿泄露給他人。
其中的{s6}會(huì)被替換為驗(yàn)證碼,而6指的是字符最大長度,超過則無法發(fā)送。
3. 基于官方API文檔實(shí)現(xiàn)短信發(fā)送
3.1 官方demo
API文檔 -> 開發(fā)引導(dǎo) -> 代碼示例 -> Java ,代碼如下
package com.ljs; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Console; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.lang.reflect.MalformedParameterizedTypeException; import java.net.URL; import java.net.URLConnection; import java.security.MessageDigest; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.lang.model.element.VariableElement; import javax.management.monitor.MonitorSettingException; import javax.print.attribute.standard.DateTimeAtCompleted; import org.junit.Test; public class MyTest { public static void main(String[] args) throws ParseException { //時(shí)間戳 long timestamp = System.currentTimeMillis(); System.out.println(timestamp); //url String url = "http://www.lokapi.cn/smsUTF8.aspx"; //簽名,在發(fā)送時(shí)使用md5加密 String beforSign = "action=sendtemplate&username=18586975869&password="+getMD5String("18586975869")+"&token=389c1a49×tamp="+timestamp; //參數(shù)串 String postData = "action=sendtemplate&username=18586975869&password="+getMD5String("18586975869")+"&token=389c1a49&templateid=CF2D56FC¶m=18586975869|666666&rece=json×tamp="+timestamp+"&sign="+getMD5String(beforSign); //調(diào)用其提供的發(fā)送短信方法 String result = sendPost(url,postData); System.out.println(result); } //發(fā)送短信的方法 public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打開和URL之間的連接 URLConnection conn = realUrl.openConnection(); // 設(shè)置通用的請求屬性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 發(fā)送POST請求必須設(shè)置如下兩行 conn.setDoOutput(true); conn.setDoInput(true); // 獲取URLConnection對象對應(yīng)的輸出流 out = new PrintWriter(conn.getOutputStream()); // 發(fā)送請求參數(shù) out.print(param); // flush輸出流的緩沖 out.flush(); // 定義BufferedReader輸入流來讀取URL的響應(yīng) in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("發(fā)送 POST 請求出現(xiàn)異常!"+e); e.printStackTrace(); }finally{ //使用finally塊來關(guān)閉輸出流、輸入流 try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result; } //用來計(jì)算MD5的函數(shù) public static String getMD5String(String rawString){ String[] hexArray = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; try{ MessageDigest md = MessageDigest.getInstance("MD5"); md.update(rawString.getBytes()); byte[] rawBit = md.digest(); String outputMD5 = " "; for(int i = 0; i<16; i++){ outputMD5 = outputMD5+hexArray[rawBit[i]>>>4& 0x0f]; outputMD5 = outputMD5+hexArray[rawBit[i]& 0x0f]; } return outputMD5.trim(); }catch(Exception e){ System.out.println("計(jì)算MD5值發(fā)生錯(cuò)誤"); e.printStackTrace(); } return null; } /** * 生成秘鑰 * * @param tm * @param key * @return */ public static String createSign(TreeMap<String, String> tm, String key) { StringBuffer buf = new StringBuffer(key); for (Map.Entry<String, String> en : tm.entrySet()) { String name = en.getKey(); String value = en.getValue(); if (!"sign".equals(name) && !"param".equals(name) && value != null && value.length() > 0 && !"null".equals(value)) { buf.append(name).append('=').append(value).append('&'); } } String _buf = buf.toString(); return _buf.substring(0, _buf.length() - 1); } /** * 將文件轉(zhuǎn)成base64 字符串 * @param path文件路徑 * @return * * @throws Exception */ public static String encodeBase64File(String path) throws Exception { File file = new File(path);; FileInputStream inputFile = new FileInputStream(file); byte[] buffer = new byte[(int) file.length()]; inputFile.read(buffer); inputFile.close(); //return new BASE64Encoder().encode(buffer); return ""; } }
3.2 文字短信-模板發(fā)送
1.請求地址,UTF8編碼請求地址:http://www.lokapi.cn/smsUTF8.aspx
2.請求協(xié)議:http
3.請求方式:采用post方式
提交請求
4.請求報(bào)文:action=sendtemplate&username=zhangsan&password=E10ADC3949BA59ABBE56E057F20F883E&token=894gbhy&templateid=638fgths¶m=手機(jī)號(hào)1|參數(shù)1|參數(shù)2@手機(jī)號(hào)2|參數(shù)1|參數(shù)2&rece=json×tamp=636949832321055780&sign=96E79218965EB72C92A54
5.參數(shù)說明
參數(shù)名稱 | 是否必須 | 描述 | 示例 |
action | 是 | 操作類型 | (固定值)action=sendtemplate |
username | 是 | 賬戶名 | username=zhangsan |
password | 是 | 賬戶密碼,密碼必須MD5加密并且取32位大寫 | password=E10ADC3949BA59ABBE56E057F20F883E |
token | 是 | 產(chǎn)品總覽頁面對應(yīng)產(chǎn)品的Token | token=894gbhy |
templateid | 是 | 模板管理報(bào)備的模板ID | templateid=638fgths |
param | 是 | 發(fā)送參數(shù),可發(fā)送一個(gè)或多個(gè)手機(jī)號(hào),建議單次提交最多5000個(gè)號(hào)碼 | 17712345678|張三|2541@13825254141|李四|2536 |
dstime | 否 | 設(shè)置要發(fā)送短信的時(shí)間,精確到秒(yyyy-MM-dd HH:mm:ss) | 2017-01-05 16:23:23 |
rece | 否 | 返回類型json、xml,默認(rèn)(json) | rece=json |
timestamp | 是 | 時(shí)間戳,13位時(shí)間戳,單位(毫秒) | timestamp=636949832321055780 |
sign | 是 | 簽名校驗(yàn) | sign=96E79218965EB72C92A54 |
param參數(shù)詳細(xì)說明
發(fā)送一個(gè)手機(jī)號(hào)模板為【手機(jī)號(hào)1|參數(shù)1|參數(shù)2】
發(fā)送多個(gè)手機(jī)號(hào)模板為【手機(jī)號(hào)1|參數(shù)1|參數(shù)2@手機(jī)號(hào)2|參數(shù)3|參數(shù)4@…】
第一列必須為手機(jī)號(hào),參數(shù)1,參數(shù)2對應(yīng)短信模板里的參數(shù)順序,英文豎線隔開, 比如短信模板為【簽名】您好,{s6},您的驗(yàn)證碼是:{s6},參數(shù)1就對應(yīng)您好后邊的{s6},參數(shù)2對應(yīng)驗(yàn)證碼是后邊的{s6}, 多個(gè)手機(jī)號(hào)以@隔開。
若模板內(nèi)沒有參數(shù)則只輸入手機(jī)號(hào)即可。
sign參數(shù)詳細(xì)說明
簽名由參數(shù)action,username,password,token,timestamp進(jìn)行MD5加密組成
比如這些值拼接后為action=sendtemplate&username=zhangsan&password=E10ADC3949BA59ABBE56E057F20F883E&token=588aaaaa×tamp=636949832321055780,那么就MD5加密這個(gè)參數(shù)字符串得到結(jié)果后作為sign的值sign=96E79218965EB72C92A54
基于官方j(luò)ava代碼和參數(shù)說明,替換自己的值,即可實(shí)現(xiàn)發(fā)送。
6.返回結(jié)果
//成功返回 { "returnstatus":"success", "code":"0", "taskID":[ { "tel_17712345678":"15913494519502337" } ] } //失敗返回 { "returnstatus":"error", "code":"-51", "remark":"訪問超時(shí)!" }
三、封裝發(fā)送短信工具類
1.添加 fastjson 的依賴,用于把返回結(jié)果轉(zhuǎn)為對象,方便處理。
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.75</version> </dependency>
2.工具類如下
public class SendSMSUtil { /** * 封裝的發(fā)驗(yàn)證碼的方法 * @param account 平臺(tái)賬戶 * @param password 平臺(tái)密碼 * @param token 平臺(tái)token * @param templateid 短信模板id * @param phone 短信接收方手機(jī)號(hào) * @param code 驗(yàn)證碼 * @return */ public static MsgResult sendMsgPost(String account,String password,String token,String templateid,String phone,String code){ //時(shí)間戳 long timestamp = System.currentTimeMillis(); //System.out.println(timestamp); //url String url = "http://www.lokapi.cn/smsUTF8.aspx"; //簽名 String beforSign = "action=sendtemplate&username="+account+"&password="+getMD5String(password)+"&token="+token+"×tamp="+timestamp; //參數(shù)串 String postData = "action=sendtemplate&username="+account+"&password="+getMD5String(password)+"&token="+token+"&templateid="+templateid+"¶m="+phone+"|"+code+"&rece=json×tamp="+timestamp+"&sign="+getMD5String(beforSign); //發(fā)送請求 String result = sendPost(url,postData); //將json結(jié)果轉(zhuǎn)為對象,方便判斷 MsgResult msgResult = JSON.parseObject(result, MsgResult.class); return msgResult; } //原本的發(fā)送方法 public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打開和URL之間的連接 URLConnection conn = realUrl.openConnection(); // 設(shè)置通用的請求屬性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 發(fā)送POST請求必須設(shè)置如下兩行 conn.setDoOutput(true); conn.setDoInput(true); // 獲取URLConnection對象對應(yīng)的輸出流 out = new PrintWriter(conn.getOutputStream()); // 發(fā)送請求參數(shù) out.print(param); // flush輸出流的緩沖 out.flush(); // 定義BufferedReader輸入流來讀取URL的響應(yīng) in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("發(fā)送 POST 請求出現(xiàn)異常!"+e); e.printStackTrace(); } finally{ //使用finally塊來關(guān)閉輸出流、輸入流 try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result; } //用來計(jì)算MD5的函數(shù) public static String getMD5String(String rawString){ String[] hexArray = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; try{ MessageDigest md = MessageDigest.getInstance("MD5"); md.update(rawString.getBytes()); byte[] rawBit = md.digest(); String outputMD5 = " "; for(int i = 0; i<16; i++){ outputMD5 = outputMD5+hexArray[rawBit[i]>>>4& 0x0f]; outputMD5 = outputMD5+hexArray[rawBit[i]& 0x0f]; } return outputMD5.trim(); }catch(Exception e){ System.out.println("計(jì)算MD5值發(fā)生錯(cuò)誤"); e.printStackTrace(); } return null; } }
用于接收返回值的對象
public class MsgResult{ //返回描述 private String returnstatus; //返回狀態(tài)碼 private Integer code; //錯(cuò)誤消息 private String remark; public String getReturnstatus() { return returnstatus; } public void setReturnstatus(String returnstatus) { this.returnstatus = returnstatus; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } @Override public String toString() { return "MsgResult{" + "returnstatus='" + returnstatus + '\'' + ", code=" + code + ", remark='" + remark + '\'' + '}'; } }
3.調(diào)用測試
public class SendSMSTest { public static void main(String[] args) throws ParseException { //使用工具類發(fā)送短信,返回封裝的對象 MsgResult msgResult = SendSMSUtil.sendMsgPost("平臺(tái)賬號(hào)","平臺(tái)密碼","token","短信模板id","接受方手機(jī)號(hào)","驗(yàn)證碼"); //進(jìn)行判斷 if("success".equals(msgResult.getReturnstatus()) && msgResult.getCode()==0){ System.out.println("發(fā)送成功"); }else{ System.out.println("發(fā)送失敗,原因是:"+msgResult.getRemark()); } } }
到此這篇關(guān)于使用Java第三方實(shí)現(xiàn)發(fā)送短信功能的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)發(fā)短信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java web項(xiàng)目里ehcache.xml介紹
java web項(xiàng)目里ehcache.xml介紹,需要的朋友可以參考一下2013-03-03Springboot?RestTemplate設(shè)置超時(shí)時(shí)間的簡單方法
學(xué)習(xí)springboot ,RestTemplate的使用場景非常非常多,比如springcloud中的服務(wù)消費(fèi),下面這篇文章主要給大家介紹了關(guān)于Springboot?RestTemplate設(shè)置超時(shí)時(shí)間的簡單方法,需要的朋友可以參考下2022-01-01從零開始學(xué)springboot整合feign跨服務(wù)調(diào)用的方法
這篇文章主要介紹了從零開始學(xué)springboot整合feign跨服務(wù)調(diào)用的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03關(guān)于Selenium的UI自動(dòng)化測試屏幕截圖功能實(shí)例代碼
今天小編就為大家分享一篇關(guān)于Selenium的UI自動(dòng)化測試屏幕截圖功能實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05Spring中的@ConfigurationProperties在方法上的使用詳解
這篇文章主要介紹了Spring中的@ConfigurationProperties在方法上的使用詳解,@ConfigurationProperties應(yīng)該經(jīng)常被使用到,作用在類上的時(shí)候,將該類的屬性取值?與配置文件綁定,并生成配置bean對象,放入spring容器中,提供給其他地方使用,需要的朋友可以參考下2024-01-01