網易雲傳送簡訊驗證碼java實現
阿新 • • 發佈:2018-12-09
首先,登陸網易雲信註冊賬號然後獲取自己的App Key與App Secret,這裡就不多說了,可以自行百度。
在服務端API中我們可以很容易的找到這段程式碼,這是用來加密用的(關於如何加密也可以找到)
import java.security.MessageDigest; public class CheckSumBuilder { // 計算並獲取CheckSum public static String getCheckSum(String appSecret, String nonce, String curTime) { return encode("sha1", appSecret + nonce + curTime); } // 計算並獲取md5值 public static String getMD5(String requestBody) { return encode(“md5”, requestBody); } private static String encode(String algorithm, String value) { if (value == null) { return null; } try { MessageDigest messageDigest = MessageDigest.getInstance(algorithm); messageDigest.update(value.getBytes()); return getFormattedText(messageDigest.digest()); } catch (Exception e) { throw new RuntimeException(e); } } private static String getFormattedText(byte[] bytes) { int len = bytes.length; StringBuilder buf = new StringBuilder(len * 2); for (int j = 0; j < len; j++) { buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]); buf.append(HEX_DIGITS[bytes[j] & 0x0f]); } return buf.toString(); } private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; }
接著在下面我們又可以找到這段模板程式碼,我們先看他的模板,具體資訊可以參考手冊然後瞭解它們的意義
import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.util.ArrayList; import java.util.Date; import java.util.List; public class Test { public static void main(String[] args) throws Exception{ DefaultHttpClient httpClient = new DefaultHttpClient(); String url = "https://api.netease.im/nimserver/user/create.action"; HttpPost httpPost = new HttpPost(url); String appKey = "94kid09c9ig9k1loimjg012345123456"; String appSecret = "123456789012"; String nonce = "12345"; String curTime = String.valueOf((new Date()).getTime() / 1000L); String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);//參考 計算CheckSum的java程式碼 // 設定請求的header httpPost.addHeader("AppKey", appKey); httpPost.addHeader("Nonce", nonce); httpPost.addHeader("CurTime", curTime); httpPost.addHeader("CheckSum", checkSum); httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); // 設定請求的引數 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("accid", "helloworld")); httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8")); // 執行請求 HttpResponse response = httpClient.execute(httpPost); // 列印執行結果 System.out.println(EntityUtils.toString(response.getEntity(), "utf-8")); } }
然後咱們把上面的程式碼稍作修改變成如下的樣子
package tool; import com.alibaba.fastjson.JSON; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 簡訊相關的工具類 * * @author 李嵐祺 */ public class SMSUtils { private static final String NONCE = "123456"; private static final String APP_SECRET = "你自己登陸所獲取的"; private static final String APP_KEY = "你自己登陸所獲取的"; /** * 驗證碼類簡訊,注意:該簡訊中驗證碼不能自己生成,由網易雲幫我們生成 * * @param mobile 手機號碼 * @param templateId 驗證碼模板ID * @return 是否傳送成功 */ public static final boolean sendCode(String mobile, String templateId) throws IOException { HttpPost httpPost = new HttpPost("https://api.netease.im/sms/sendcode.action"); String currentTime = String.valueOf(new Date().getTime()/1000L); String checkSum = CheckSumBuilder.getCheckSum(APP_SECRET,NONCE,currentTime); //set header httpPost.setHeader("AppKey",APP_KEY); httpPost.setHeader("CurTime",currentTime); httpPost.setHeader("Nonce",NONCE); httpPost.setHeader("CheckSum",checkSum); httpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); //set data List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>(); nameValuePairList.add(new BasicNameValuePair("mobile",mobile)); nameValuePairList.add(new BasicNameValuePair("templateid", templateId)); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList,"utf-8")); //start request CloseableHttpClient closeableHttpClient = HttpClients.createDefault(); HttpResponse httpResponse = closeableHttpClient.execute(httpPost); String responseResult = EntityUtils.toString(httpResponse.getEntity(),"utf-8"); System.out.println("responseResult:"+responseResult); String stateCode = JSON.parseObject(responseResult).getString("code"); if(stateCode.equals("200")){ return true; } return false; } /** * 判斷使用者輸入驗證碼與網易雲生成的驗證碼是否一致 * * @param mobile 電話號碼 * @param code 傳送到mobile上的簡訊 */ public static final boolean verifyCode(String mobile, String code) throws IOException { HttpPost httpPost = new HttpPost("https://api.netease.im/sms/verifycode.action"); String currentTime = String.valueOf(new Date().getTime()/1000L); String checkSum = CheckSumBuilder.getCheckSum(APP_SECRET,NONCE,currentTime); //set header httpPost.setHeader("AppKey",APP_KEY); httpPost.setHeader("CurTime",currentTime); httpPost.setHeader("Nonce",NONCE); httpPost.setHeader("CheckSum",checkSum); httpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); //set data List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>(); nameValuePairList.add(new BasicNameValuePair("code",code)); nameValuePairList.add(new BasicNameValuePair("mobile",mobile)); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList,"utf-8")); //start request CloseableHttpClient closeableHttpClient = HttpClients.createDefault(); HttpResponse httpResponse = closeableHttpClient.execute(httpPost); String responseResult = EntityUtils.toString(httpResponse.getEntity(),"utf-8"); System.out.println("responseResult:"+responseResult); String stateCode = JSON.parseObject(responseResult).getString("code"); if(stateCode.equals("200")){ return true; } return false; } }
接下來就是測試了,我們來一個簡單的程式碼來試一試
import java.io.IOException;
import java.util.Scanner;
import tool.SMSUtils;
public class Test1 {
private static String mobile = "你需要傳送簡訊的手機號";
public static void main(String[] args) {
try {
SMSUtils.sendCode(mobile, "模板號(在裡面有你自己設定的傳送格式)");
} catch (IOException e) {
e.printStackTrace();
}
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入你收到的驗證碼");
String code = scanner.nextLine();
try {
if(SMSUtils.verifyCode(mobile, code)) {
System.out.println("校驗成功");
}else {
System.out.println("校驗失敗");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
一番操作下來之後就大功告成了,下面我們結合web來一起試一下(運用了一點點非同步),有關於這非同步,不知道的可以稍微去看看,不會用太多時間的
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<script type="text/javascript" src="./js/jquery-3.3.1.js"></script>
<script>
function sendcode(){
var ajaxObject={
url:"./SendcodeServlet",
type:"GET",
data:{
mobile:document.getElementById("mobile").value,
},
dataType:"text",
success:function(data){
}
}
$.ajax(ajaxObject);
}
function checkcode(){
var ajaxObject={
url:"./CheckcodeServlet",
type:"GET",
data:{mobile:document.getElementById("mobile").value,
code:document.getElementById("code").value
},
dataType:"text",
success:function(data){
}
}
$.ajax(ajaxObject);
}
</script>
</head>
<body>
<input name="mobile" id="mobile" placeholder="請輸入手機號" value=""/><br />
<input name="code" id="code" placeholder="請輸入驗證碼" value=""/><br />
<button onclick="sendcode()">傳送驗證碼</button>
<button onclick="checkcode()">提交</button>
</body>
</html>
接下來是倆個Servlet
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import tool.SMSUtils;
public class SendcodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static String templateId = "4003516";
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String mobile = request.getParameter("mobile");
System.out.println(mobile);
SMSUtils.sendCode(mobile, templateId);
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import tool.SMSUtils;
public class CheckcodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String code = request.getParameter("code");//使用者輸入的驗證碼
String mobile = request.getParameter("mobile");
System.out.println(code);
if(SMSUtils.verifyCode(mobile,code)) {
System.out.println("成功");
//驗證成功跳轉到成功介面
request.getRequestDispatcher("success.jsp").forward(request, response);
}else {
System.out.println("失敗");
}
}
}
不過在這裡我有一個疑問就是最後驗證出來是成功,也列印了出來,但是那個跳轉介面不知道為什麼沒有出現,然而到這時候我的簡訊已經全部發送完了,沒有剩餘的存貨了,有點尷尬。。。。。。先留個坑,或許之後寫類似的專案的時候我就知道了。
我覺得實現這種功能比較重要的一點就是學會去看開發者API,裡面有各種介紹,還有好多東西我也沒怎麼看,但單單看這倆種就能實現驗證碼的傳送與校驗了。