首先下载所需jar包:commons-logging-1.1.1.jar,commons-httpclient-3.1.jar,commons-codec-1.4.jar 。
到网站注册好账号,记下自己的账户和密钥(不是登录密码)。
签名就是短信最开始【】括住的部分。
发送短信生成验证码的工具类:
importorg.apache.commons.httpclient.Header;importorg.apache.commons.httpclient.HttpClient;importorg.apache.commons.httpclient.HttpException;importorg.apache.commons.httpclient.NameValuePair;importorg.apache.commons.httpclient.methods.PostMethod;importjava.io.IOException;importjava.util.HashMap;importjava.util.Random;public classSendMessage {public static void main(String[] args) throwsException{
SendMessage sendMessage= newSendMessage();
sendMessage.getMessageStatus("你的手机号码");
}public HashMap getMessageStatus(String phone) throwsHttpException, IOException {
HashMap m = new HashMap();//http协议
HttpClient client = newHttpClient();//连接第三方平台
PostMethod post = new PostMethod("http://gbk.api.smschinese.cn/");
post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=gbk");//在头文件中设置转码//生成六位验证码
String charValue = "";for (int i = 0; i < 6; i++) {char c = (char) (randomInt(0, 9) + '0');
charValue+=String.valueOf(c);
}//短信模板
NameValuePair[] data ={new NameValuePair("Uid", "scxdhr"), //sms短信通 注册的用户名
new NameValuePair("Key", "d41d8cd98f00b204e980"), //密匙
new NameValuePair("smsMob",phone),//要发送的手机号
new NameValuePair("smsText","您的验证码是:"+charValue)//短信内容
};
post.setRequestBody(data);
client.executeMethod(post);//获取http头
Header[] headers =post.getResponseHeaders();int statusCode =post.getStatusCode();
System.out.println("statusCode:"+statusCode);for(Header h:headers){
System.out.println(h.toString());
}//获取返回消息
String result = new String(post.getResponseBodyAsString().getBytes("gbk"));
System.out.println(result);//打印返回消息状态//将返回消息和6位数验证码放入到m列表里面
m.put("result", result);
m.put("code", charValue);//断开与第三方平台的连接
post.releaseConnection();returnm;
}//生成验证码
public static int randomInt(int from, intto) {
Random r= newRandom();return from + r.nextInt(to -from);
}
}
result返回“1”就表示发送成功,手机上也会收到短信。
有三种方法在后台获得手机验证码:
1.使用session的setAttribute方法,把数据存到页面缓存中,但是关了页面之后,储存的验证码就会失效,所以不推荐使用这种方法。
2.使用redis数据库缓存验证码,redis数据库用来做这个契合度非常高,还能设置缓存失效时间,写起来非常简单。
3.写了一个工具类CacheUtil,一个缓存用的map,也可以设置数据的失效时间,下面贴上代码:
importjava.util.Map;import java.util.concurrent.*;/*** 缓存工具类
*
*@authorlance
*@since2018-10-25*/
public classCacheUtil
{/*** 存储需缓存数据的map*/
private final static Map MAP = new ConcurrentHashMap<>();/*** 定时器线程池,用于清除过期缓存*/
private final static ScheduledExecutorService EXECUTOR =Executors.newSingleThreadScheduledExecutor();/*** 添加缓存
*
*@paramkey map的key
*@paramdata map的value*/
public synchronized static voidput(String key, Object data)
{
CacheUtil.put(key, data,0);
}/*** 添加缓存
*
*@paramkey map的key
*@paramdata map的value
*@paramexpire 过期时间,单位:毫秒, 0表示无限长*/
public synchronized static void put(String key, Object data, longexpire)
{//清除原map
CacheUtil.remove(key);//设置过期时间
if (expire > 0)
{
Future future= EXECUTOR.schedule(() ->{//过期后清除该map
synchronized (CacheUtil.class)
{
MAP.remove(key);
}
}, expire, TimeUnit.MILLISECONDS);
MAP.put(key,newEntity(data, future));
}else{//不设置过期时间
MAP.put(key, new Entity(data, null));
}
}/*** 校验缓存中是否存在key
*
*@paramkey map的key
*@return是否存在key*/
public synchronized static booleankeyExists(String key)
{return MAP.get(key) != null;
}/*** 读取缓存
*
*@paramkey map的key
*@returnmap的value*/
public synchronized staticObject get(String key)
{
Entity entity=MAP.get(key);return entity == null ? null: entity.getValue();
}/*** 读取缓存
*
*@paramkey 键
*@paramcls 值类型
*@returnmap中value存储的对象*/
public synchronized static T get(String key, Classcls)
{returncls.cast(CacheUtil.get(key));
}/*** 清除缓存
*
*@paramkey map的key
*@return
*/
public synchronized static voidremove(String key)
{//清除原缓存数据
Entity entity =MAP.remove(key);//清除原map定时器
if (null !=entity)
{
Future future=entity.getFuture();if (future != null)
{
future.cancel(true);
}
}
}/*** 缓存实体类*/
private static classEntity
{/*** map的值*/
privateObject value;/*** 定时器*/
privateFuture future;privateEntity(Object value, Future future)
{this.value =value;this.future =future;
}/*** 获取map值
*
*@returnmap值*/
publicObject getValue()
{returnvalue;
}/*** 获取Future对象
*
*@returnFuture对象*/
privateFuture getFuture()
{returnfuture;
}
}
}
剩下的就是校验手机和前台发送过来的验证码是否一致,不再赘述。