网站接入短信平台验证流程
以网站注册用户为例
前端页面,此处用到volicity前端验证,暂时不做深入
<form action="$!webPath/register_finish.htm" method="post" name="theForm" id="theForm"> <table width="900" border="0" cellpadding="0" cellspacing="0" class="regist_common_table"> <tr> <td width="70" align="right">手机号:</td> <td><div class="regist_form_txt"><input name="userName" type="text" id="userName" class="regist_txt" /></div></td> </tr> <tr> <td width="120"align="right">短信验证码:</td> <td> <div class="regist_form_txt"><input name="code" type="text" id="code" class="regist_txt1"/></div> <a href="javascript:void(0);" onclick="generic_mobile_verify_code();" id="mobile_verify_code_generic" class="get_code_generic" style="margin-left:7px;line-height:28px;">获取验证码</a> </td> </tr> <!-- <tr> <td align="right">邮箱:</td> <td><div class="regist_form_txt"><input name="email" type="text" id="email" class="regist_txt" /></div></td> </tr> --> <tr> <td align="right">登陆密码:</td> <td><div class="regist_form_txt"><input name="password" type="password" id="password" class="regist_txt" /></div></td> </tr> #if($!config.securityCodeRegister) <script> function refreshCode(){ jQuery("#code_img").attr("src","$!webPath/verify.htm?d"+new Date().getTime()); } </script> <tr> <td align="right">验证码:</td> <td> <div class="regist_form_txt"><input name="code" type="text" class="regist_code" id="code" /></div> #if($!config.securityCodeType=='voice') <script> function readCode(id){ var s = "<embed id='sound_play' name='sound_play' src='$!webPath/resources/flash/soundPlayer.swf?" + (new Date().getTime()) + "' FlashVars='url=$!webPath"+ "' width='0' height='0' allowScriptAccess='always' type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/go/getflashplayer' /></embed>"; jQuery("#"+id).html(s); } </script> <b class="regist_code_img"><img id="code_img" src="$!webPath/verify.htm" width="59" height="27" style="display:none;" /></b> <a href="javascript:void(0);" onclick="readCode('player')" title="朗读验证码" class="code_speech"></a> <a href="javascript:void(0);" onclick="refreshCode();" class="code_refresh"></a> <span id="player"></span> #else <b class="regist_code_img"><img id="code_img" src="$!webPath/verify.htm" width="59" height="27" /></b><a href="javascript:void(0);" onclick="refreshCode();" class="code_refresh"></a> #end </td> </tr> #end <tr> <td> </td> <td class="font12"> <div class="regist_form_txt"> <input name="agree" type="checkbox" class="regist_check" id="agree" value="true" checked="checked" /> <label for="agree">我已阅读并同意 </label> <a href="javascript:void(0);" onclick="jQuery('#agree_article').show();" class="blue2">《商城在线服务协议》</a></div> </td> </tr> <tr> <td> </td> <td><input name="" type="submit" class="regist_btn" value="立即注册"/></td> </tr> </table> </form>
js代码部分:
var time=60; var time_id=""; function generic_mobile_verify_code(){ var mobile=jQuery("#userName").val(); if(isMobil(mobile)){ jQuery.post("$!webPath/buyer/register_account_mobile_sms.htm",{"type":"mobile_vetify_code","mobile":mobile},function(data){ if(data=="100"){ alert("短信发送成功"); jQuery("#mobile_verify_code_generic").hide(); time_id=setInterval(countDown,1000); } if(data=="200"){ alert("短信发送失败"); } if(data=="400"){ alert("手机号码已经注册,短信发送失败"); } if(data=="300"){ alert("商城未开启短信服务"); } },"text"); }else{ alert("请输入正确的手机号码"); } } function countDown(){ --time; jQuery("#time_out_generic").html(time+"秒后可以重新获取,验证码15分钟有效"); if(time==0){ clearInterval(time_id); jQuery("#time_out_generic").html(""); jQuery("#mobile_verify_code_generic").show(); time=10; } }
异步执行的方法:
@SecurityMapping(title = "手机短信发送", value = "/buyer/register_account_mobile_sms.htm*", rtype = "buyer", rname = "用户中心", rcode = "user_center", rgroup = "用户中心") @RequestMapping("/buyer/register_account_mobile_sms.htm") public void register_account_mobile_sms(HttpServletRequest request, HttpServletResponse response, String type, String mobile) throws UnsupportedEncodingException { String ret = "100"; System.out.println("后台传入的手机号是:"+mobile); System.out.println("后台传入的类型是:"+type); if (type.equals("mobile_vetify_code")) { String code = CommUtil.randomString(4).toUpperCase(); //生成验证码的工具类 User user = this.userService.getObjByProperty("telephone", mobile); //从数据库查找手机号码是否注册 if(user != null && !user.equals("")){ ret = "400"; }else{ String content = code + "。[" + this.configService.getSysConfig().getTitle() + "]"; if (this.configService.getSysConfig().isSmsEnbale()) { //调用云片的短信网关 boolean ret1 = SmsUtils.sendMessage(mobile, content); if (ret1) { VerifyCode mvc = null; try{ mvc = this.mobileverifycodeService .getObjByProperty("username", mobile); }catch(Exception e){ if (mvc == null) { mvc = new VerifyCode(); //此处是存入数据库的实体类,用于后台比较验证码 mvc.setAddTime(new Date()); mvc.setCode(code); mvc.setMobile(mobile); this.mobileverifycodeService.save(mvc); }else { mvc.setAddTime(new Date()); mvc.setCode(code); mvc.setMobile(mobile); mvc.setUserName(mobile); this.mobileverifycodeService.update(mvc); } } /*VerifyCode mvc = new VerifyCode(); mvc.setAddTime(new Date()); mvc.setCode(code); mvc.setMobile(mobile); this.mobileverifycodeService.save(mvc);*/ } else { ret = "200"; } } else { ret = "300"; } } response.setContentType("text/plain"); response.setHeader("Cache-Control", "no-cache"); response.setCharacterEncoding("UTF-8"); PrintWriter writer; try { writer = response.getWriter(); writer.print(ret); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
方法中调用的随机生成n位数的工具类: CommUtil.randomString(n).toUpperCase();
public static final String randomString(int length) { char[] numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz" + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray(); if (length < 1) { return ""; } Random randGen = new Random(); char[] randBuffer = new char[length]; for (int i = 0; i < randBuffer.length; i++) { randBuffer[i] = numbersAndLetters[randGen.nextInt(71)]; } return new String(randBuffer); }
调用云片的短信网关的工具类:
package com.sdsanmi.utils;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 短信工具类
* @author lld
*
*/
public class SmsUtils {
private static final Log logger = LogFactory.getLog(SmsUtils.class);
/**
* 发送短信验证码
* @param mobileNo String
* -手机号码
* @param vals String
* -短信内容
*/
public static boolean sendMessage(String mobileNo,String vals){
Map<String,Object> resultMap = new HashMap<String,Object>();
boolean success = false;
String msg = "";
try {
//新版短信验证,暂时注释
// if(SMSTool.sendMessage(mobileNo, vals))
if(SendMessageTool.sendMessage(mobileNo, vals)) //接入云片短信验证,原华信弃用
{
success = true;
msg="发送成功";
}
else
{
msg="发送失败";
}
} catch (Exception e) {
logger.error("sendMsg error:"+mobileNo,e);
}
resultMap.put(CommonConstants.RET_RS, success);
resultMap.put(CommonConstants.RET_MSG, msg);
return success;
}
}
云片短信demo 地址:https://www.yunpian.com/,所依赖的jar包,此部分和官方api一致
/**
* @Description:直接调用云片的后台发送验证码,需要传递单位名称,手机号和验证码信息
* 短信账号信息写死在本类中,不在通过配置文件配置
* @Company:山东三米信息技术有限公司
* @author xuzhiguo
* @date 2017-08-16
* @version 1.0
*/
package com.sdsanmi.utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
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 org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPMessage;
public class SendMessageTool
{
//查账户信息的http地址
private static String URI_GET_USER_INFO = "https://sms.yunpian.com/v2/user/get.json";
//智能匹配模版发送接口的http地址
private static String URI_SEND_SMS = "https://sms.yunpian.com/v2/sms/single_send.json";
//模板发送接口的http地址
private static String URI_TPL_SEND_SMS = "https://sms.yunpian.com/v2/sms/tpl_single_send.json";
//发送语音验证码接口的http地址
private static String URI_SEND_VOICE = "https://voice.yunpian.com/v2/voice/send.json";
//编码格式。发送编码格式统一用UTF-8
private static String ENCODING = "UTF-8";
/**
* 通过云片平台发送验证码
* @param phone
* @param verifyNo
* @return
*/
public static boolean sendMessage(String phone,String verifyNo) throws Exception
{
boolean flag = false;
//修改为您的apikey.apikey可在官网(http://www.yuanpian.com)登录后获取
String apikey = "*****这个不能暴露****";
//修改为您要发送的手机号
String mobile = URLEncoder.encode(phone,ENCODING);
/**************** 查账户信息调用示例 *****************/
System.out.println(SendMessageTool.getUserInfo(apikey));
/**************** 使用智能匹配模版接口发短信(推荐) *****************/
//设置您要发送的内容(内容必须和某个模板匹配。以下例子匹配的是系统提供的1号模板)
String text = "【东地美商城】亲,您的验证码:"+verifyNo+"(如非本人操作,请忽略)";
//发短信调用示例
String sms = SendMessageTool.sendSms(apikey, text, mobile);
System.out.println(sms);
//{"code":0,"msg":"发送成功","count":1,"fee":0.05,"unit":"RMB","mobile":"15628989008","sid":17018239170}
// System.out.println(sms.subSequence(8, 9));
if (sms.subSequence(8, 9).toString().equals("0")) {
flag = true;
System.out.println("发送的短信信息是:"+text);
// System.out.println(flag);
}
return flag;
}
/**
* 取账户信息
*
* @return json格式字符串
* @throws java.io.IOException
*/
public static String getUserInfo(String apikey) throws IOException, URISyntaxException {
Map<String, String> params = new HashMap<String, String>();
params.put("apikey", apikey);
return post(URI_GET_USER_INFO, params);
}
/**
* 智能匹配模版接口发短信
*
* @param apikey apikey
* @param text 短信内容
* @param mobile 接受的手机号
* @return json格式字符串
* @throws IOException
*/
public static String sendSms(String apikey, String text, String mobile) throws IOException {
Map<String, String> params = new HashMap<String, String>();
params.put("apikey", apikey);
params.put("text", text);
params.put("mobile", mobile);
return post(URI_SEND_SMS, params);
}
/**
* 基于HttpClient 4.3的通用POST方法
*
* @param url 提交的URL
* @param paramsMap 提交<参数,值>Map
* @return 提交响应
*/
public static String post(String url, Map<String, String> paramsMap) {
CloseableHttpClient client = HttpClients.createDefault();
String responseText = "";
CloseableHttpResponse response = null;
try {
HttpPost method = new HttpPost(url);
if (paramsMap != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> param : paramsMap.entrySet()) {
NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
paramList.add(pair);
}
method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
}
response = client.execute(method);
HttpEntity entity = response.getEntity();
if (entity != null) {
responseText = EntityUtils.toString(entity);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return responseText;
}
//测试用
public static void main(String[] args)
{
try
{
sendMessage("15628989008","121121");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}