短信验证码跟自己在Servlet画的验证码不一样,我们不用管短信验证码是怎么产生的,我们只需要关注如何调用短信验证码,在短信验证码里面添加
自己需要的随机数或者其他的内容。
现在直接上流程
第一步找一个给用户发送短信的短信平台,我这里用的秒滴科技的短信平台,新人注册有10元的免费额度,一条短信几分,够我们测试用了。
第二步 找到配置管理里面的验证码短信模板自己写好申请过了就可以备用了。如下图所示
第三步 在右上角有个API文档点进去,左边有个开发者中心,里面有个Https API 点开里面有个验证码通知短信,这个是这个短信平台接口的规则,必须要满足平台接口的要求的参数
还有下面的必选参数如下图截图,必选的参数待会再后台都必选要有不然会报错。
第四步 进入Eelipse写我们的后台代码 。直接上代码我的方法是在Dao层里面写的,自己定义了一个SmsDao短信验证码的持久接口。
package www.meizu.com.dao.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import www.meizu.com.dao.SmsDao;
/**
* 生产短信验证码持久接口实现类
* @author Administrator
*
*/
public class SmsDaoImpl implements SmsDao{
//这里的3个String 属性对应的用户中心里的开发者信息里面的ACCOUNT SID 和 AUTHTOKEN 还有验证码通知短信接口中的请求地址这3个属性待会需要用到
private String sendUrl="https://api.miaodiyun.com/20150822/industrySMS/sendSMS";
private String ACCOUNTSID="d85da4485e094a5296c2d401f459d487";
private String AUTHTOKEN="e225e0ef637046bc8eb72818923a808c";
然后我们开始满足平台的必要的参数。当然我们从最简单的参数开始满足,我首先满足的时间戳这个参数,方法很简单如以下代码
/**
* 获取时间戳,生产短信验证码需要时间戳
* @return
*/
public static String getTimeStamp(){
return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}
然后在满足短信签名,平台要求需要MD5加密,32位小写
/**
* 短信签名,生产短信验证码需要签名
* 签名。MD5(ACCOUNT SID + AUTH TOKEN + timestamp)共32位(小写)。
* @param sdk 开发者账号
* @param token 开发者密码
* @param timeStamp 时间戳
* @return
*/
public static String getMD5(String sdk,String token,String timeStamp){
StringBuilder sb=new StringBuilder();
String source=sdk+token+timeStamp;
try {
MessageDigest md=MessageDigest.getInstance("MD5");
byte[] b=md.digest(source.getBytes());
for (byte c : b) {
String hex=Integer.toHexString(c&0xff);
if(hex.length()==1){
sb.append("0"+hex);
}else{
sb.append(hex);
}
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return sb.toString();
然后是请求参数拼接,注释的模板是API文档上的模板复制API文档上的就可以了,每个人的请求参数模板好像都不一样
/**
* 请求参数拼接
* @param accounSid
* @param smsContent
* @param to
* @param timestamp
* @param sig
* @param respDataType
* @return 返回拼接好的参数
*/
public static String pinJie(String accounSid,String smsContent,String to,String timestamp,String sig,String respDataType){
//accountSid=a14f6bfd43ce44c9b019de57f4e2de4b&smsContent=【秒嘀科技 to】您的验证码是345678,30分钟输入有效。
//&to=13896543210×tamp=20150821100312&sig=a14f6bfd43ue44c9b019du57f4e2ee4r&respDataType=JSON
return "accountSid="+accounSid+"&smsContent="+smsContent+"&to="+to+"×tamp="+timestamp+"&sig="+sig+"&respDataType="+respDataType;
}
然后生成短信验证码里面的数字
/**
* 生成短信验证码
* @return 返回验证码
*/
public static String smsCode(){
String code=new Random().nextInt(1000000)+"";
if(code.length()!=6){
return smsCode();//不够6位,再次调用自己的方法,递归
}else{
return code;
}
}
接下来往平台发送我们参数
@Override
public String getSmsCode(String phone) {
String smsCode=smsCode();//获取随机短信验证码
code=smsCode;
String timeStamp=getTimeStamp();//获取时间戳
String md5=getMD5(ACCOUNTSID,AUTHTOKEN,timeStamp);//获取签名
String smsMoban="【j37】尊敬的用户,您的验证码为"+smsCode;
StringBuilder sb=new StringBuilder();
try {
URL url=new URL(sendUrl);//导net的包
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");//设置传送数据的方式
connection.setDoInput(true);//设置是否允许数据写入
connection.setDoOutput(true);//设置是否允许数据输出
connection.setConnectTimeout(5000);//设置连接时间
connection.setReadTimeout(10000);//设置读取参数的时间
connection.setRequestProperty("Content-type","application/x-www-form-urlencoded");//设置请求头
String args=pinJie(ACCOUNTSID,smsMoban,phone,timeStamp,md5,"JSON");
System.out.println(args);
osw=new OutputStreamWriter(connection.getOutputStream(),"UTF-8");
osw.write(args);
osw.flush();
//读取返回参数
br=new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
String temp="";
while((temp=br.readLine())!=null){
sb.append(temp);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
代码比较分散这里上一个完整的方法代码
package www.meizu.com.dao.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import www.meizu.com.dao.SmsDao;
/**
* 生产短信验证码持久接口实现类
* @author Administrator
*
*/
public class SmsDaoImpl implements SmsDao{
//这里的3个String 属性对应的用户中心里的开发者信息里面的ACCOUNT SID 和 AUTHTOKEN 还有验证码通知短信接口中的请求地址这3个属性待会需要用到
private String sendUrl="https://api.miaodiyun.com/20150822/industrySMS/sendSMS";
private String ACCOUNTSID="d85da4485e094a5296c2d401f459d487";
private String AUTHTOKEN="e225e0ef637046bc8eb72818923a808c";
OutputStreamWriter osw=null;
BufferedReader br=null;
private String code="";
/**
* 获取6位数验证码的方法
* @return
*/
public String getCode(){
return code;
}
@Override
public String getSmsCode(String phone) {
String smsCode=smsCode();//获取随机短信验证码
code=smsCode;
String timeStamp=getTimeStamp();//获取时间戳
String md5=getMD5(ACCOUNTSID,AUTHTOKEN,timeStamp);//获取签名
String smsMoban="【j37】尊敬的用户,您的验证码为"+smsCode;
StringBuilder sb=new StringBuilder();
try {
URL url=new URL(sendUrl);//导net的包
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");//设置传送数据的方式
connection.setDoInput(true);//设置是否允许数据写入
connection.setDoOutput(true);//设置是否允许数据输出
connection.setConnectTimeout(5000);//设置连接时间
connection.setReadTimeout(10000);//设置读取参数的时间
connection.setRequestProperty("Content-type","application/x-www-form-urlencoded");//设置请求头
String args=pinJie(ACCOUNTSID,smsMoban,phone,timeStamp,md5,"JSON");
System.out.println(args);
osw=new OutputStreamWriter(connection.getOutputStream(),"UTF-8");
osw.write(args);
osw.flush();
//读取返回参数
br=new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
String temp="";
while((temp=br.readLine())!=null){
sb.append(temp);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 获取时间戳,生产短信验证码需要时间戳
* @return
*/
public static String getTimeStamp(){
return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}
/**
* 短信签名,生产短信验证码需要签名
* 签名。MD5(ACCOUNT SID + AUTH TOKEN + timestamp)共32位(小写)。
* @param sdk 开发者账号
* @param token 开发者密码
* @param timeStamp 时间戳
* @return
*/
public static String getMD5(String sdk,String token,String timeStamp){
StringBuilder sb=new StringBuilder();
String source=sdk+token+timeStamp;
try {
MessageDigest md=MessageDigest.getInstance("MD5");
byte[] b=md.digest(source.getBytes());
for (byte c : b) {
String hex=Integer.toHexString(c&0xff);
if(hex.length()==1){
sb.append("0"+hex);
}else{
sb.append(hex);
}
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 生成短信验证码
* @return 返回验证码
*/
public static String smsCode(){
String code=new Random().nextInt(1000000)+"";
if(code.length()!=6){
return smsCode();//不够6位,再次调用自己的方法,递归
}else{
return code;
}
}
/**
* 请求参数拼接
* @param accounSid
* @param smsContent
* @param to
* @param timestamp
* @param sig
* @param respDataType
* @return 返回拼接好的参数
*/
public static String pinJie(String accounSid,String smsContent,String to,String timestamp,String sig,String respDataType){
//accountSid=a14f6bfd43ce44c9b019de57f4e2de4b&smsContent=【秒嘀科技 to】您的验证码是345678,30分钟输入有效。
//&to=13896543210×tamp=20150821100312&sig=a14f6bfd43ue44c9b019du57f4e2ee4r&respDataType=JSON
return "accountSid="+accounSid+"&smsContent="+smsContent+"&to="+to+"×tamp="+timestamp+"&sig="+sig+"&respDataType="+respDataType;
}
}
短信验证码的方法就写完了,前台点击通过ajax异步请求发送给后台,后台产生结果发送给平台。流程就完了。