一 简介
短信验证码是开发过程中的一个重要的功能,百度了一下,目前提供短信服务的第三方接口有很多,常用的有以下三种:
1、秒嘀科技 - 短信接口、短信验证码、语音验证码、短信平台
最低充值120,单价0.048元/条;一次性充值36000时,单价0.036/条
2、容联云通讯_提供通话、短信、视频、呼叫中心、IM、流量等通讯能力
基础价0.06元/条;当一年期帐内余额达到30000时,单价0.045/条
3、创蓝-253.com为您的每一条短信验证码负责!
最低充值3600,单价0.06元/条;一次性充值50000时,单价0.05/条
对java接口文档的支持,三家都还不错;短信接收速度都在十秒之内(测试期间),可以接受;
个人开发者,推荐使用秒嘀科技,价格相对便宜的多,短信接收速度也在伯仲之间。
二 . 完整案例
工具类SMSUtil.java
package com.code.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import org.apache.commons.codec.digest.DigestUtils;
public class SMSUtil {
/**
* 请求地址url
*/
public static final String URL = "https://api.miaodiyun.com/20150822/industrySMS/sendSMS";
/**
* 开发者注册后系统自动生成的账号,可在官网登录后查看
*/
public static final String ACCOUNT_SID = "9d8ee64dc19d49f7b8af8f**********";
/**
* 开发者注册后系统自动生成的TOKEN,可在官网登录后查看
*/
public static final String AUTH_TOKEN = "b8eb0bde2ef94b369949***********";
/**
* 响应数据类型, JSON或XML
*/
public static final String RESP_DATA_TYPE = "json";
/**
* 构造通用参数timestamp、sig和respDataType
*
* @return
*/
public static String createCommonParam() {
// 时间戳
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String timestamp = sdf.format(new Date());
// 签名
String sig = DigestUtils.md5Hex(ACCOUNT_SID + AUTH_TOKEN + timestamp);
return "×tamp=" + timestamp + "&sig=" + sig + "&respDataType="
+ RESP_DATA_TYPE;
}
// 生成一个随机字符串
public static String generateCheckCode(int n) {
//String chars = "0123456789";
String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] rands = new char[n];
Random rd = new Random();
for (int i = 0; i < n; i++) {
// 0-35之间的一个随机数
int rand = rd.nextInt(chars.length());
rands[i] = chars.charAt(rand);
}
return new String(rands);
}
/**
* post请求
*
* @param url
* 功能和操作
* @param body
* 要post的数据
* @return
* @throws IOException
*/
public static String post(String url, String body) throws IOException {
String result = "";
OutputStreamWriter out = null;
BufferedReader in = null;
try {
URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
// 设置连接参数
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setConnectTimeout(5000);
conn.setReadTimeout(20000);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
// 提交数据
out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
out.write(body);
out.flush();
// 读取返回数据
in = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "UTF-8"));
String line = "";
boolean firstLine = true; // 读第一行不加换行符
while ((line = in.readLine()) != null) {
if (firstLine) {
firstLine = false;
} else {
result += System.lineSeparator();
}
result += line;
}
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
return result;
}
/**
* 发送验证码通知短信
*
* @param to
* 指发给谁,手机号,如:1359875489
* @param code
* 随机验证码
*/
public static String send(String to, String code) throws IOException {
//短信模板,需要登录官网设置
String smsContent = "【*******】登录验证码:" + code + ",如非本人操作,请忽略此短信。";
String tmpSmsContent = null;
tmpSmsContent = URLEncoder.encode(smsContent, "UTF-8");
String body = "accountSid=" + ACCOUNT_SID + "&to=" + to
+ "&smsContent=" + tmpSmsContent + createCommonParam();
// 提交请求
String result = post(URL, body);
System.out.println("result==>"+result);
return result;
}
}
后台servlet
package com.code.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.code.utils.SMSUtil;
public class CreateCodeServlet extends HttpServlet {
private static final long serialVersionUID = -5331539499741672015L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String phone=request.getParameter("phone");
PrintWriter out=response.getWriter();
String code=SMSUtil.generateCheckCode(4);
System.out.println("checkcode:"+code);
String result="";
try {
result=SMSUtil.send(phone, code);
} catch (IOException e) {
e.printStackTrace();
}
HttpSession session=request.getSession();
session.setAttribute("smsCode", new String(code));
out.print(result);
out.flush();
out.close();
}
}
result的结果是
发送错误:
result==>{"respCode":"00134","respDesc":"没有和内容匹配的模板"}
发送正确:
result==>{"respCode":"00000","respDesc":"请求成功。","failCount":"0","failList":[],"smsId":"f5d6ec80a8bc4291af8f6d9b7c6555fb"}
需要短信验证的登录界面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>用户登录</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<style type="text/css">
#show{ margin:auto;width:400px;}
.code{ vertical-align: middle;}
</style>
<script src="js/jquery.min.js"></script>
<script type="text/javascript">
function jishi(num){
var tt=window.setTimeout(btnShow,num);
}
function btnShow(){
$("#send").removeAttr("disabled");
}
$(document).ready(function(e){
$("#send").click(function(e){
$(this).attr("disabled","disabled");
jishi(10000);
var phoneValue=$("[name=phone]").val();
$.post("CreateCode.php","phone="+phoneValue,function(result){
var rsJson=$.parseJSON(result);
if(rsJson.respCode!="00000"){
window.alert("发送失败,请稍后再试");
}
});
});
});
</script>
</head>
<body>
<div id="show">
<h2>用户登陆</h2>
<form action="Login.php" method="post">
<table border="1px">
<tr><td>请输入用户名:</td><td><input class="tt" type="text" name="userName" /></td></tr>
<tr><td>请输入密码:</td><td><input class="tt" type="password" name="passWord" /></td></tr>
<tr><td>请输入手机号码:</td><td><input class="tt" type="text" name="phone" /></td></tr>
<tr><td>请输入验证码:</td><td><input class="code" type="text" name="inputCode" />
<input type="button" value="发送" id="send"/></td></tr>
<tr><td colspan="2" align="center"><input type="submit" value="登陆"/>
<input type="reset" value="重置"/></td></tr>
</table>
</form>
</div>
</body>
</html>
效果图:
登录的servlet如下:
package com.code.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.code.dao.UserDao;
import com.code.dao.UserDaoImpl;
public class LoginControl extends HttpServlet {
private static final long serialVersionUID = -907454493319619477L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
HttpSession session=request.getSession();
String userName=request.getParameter("userName");
String passWord=request.getParameter("passWord");
//表单里面获取的验证码,用户输入的
String userCode=request.getParameter("inputCode");
userCode=userCode.toUpperCase();
UserDao userDao=new UserDaoImpl();
boolean flag=userDao.login(userName,passWord);
if(flag){
session.setAttribute("userName",userName);
//session里面是系统生成的
String checkCode=(String)session.getAttribute("smsCode");
if(!checkCode.equals(userCode)){
out.println("<script type='text/javascript'>");
out.println("window.alert('验证码错误');");
out.println("window.location='Login.jsp';");
out.println("</script>");
}else{
response.sendRedirect("index.jsp");
}
}else{
out.println("<script type='text/javascript'>");
out.println("window.alert('用户名或密码错误');");
out.println("window.location='Login.jsp';");
out.println("</script>");
}
}
}