最近搞了一个互联网项目的注册,需要写一个手机号验证(由于之前没有*,只能自己摸索了);
1:基本思路:
1>购买了阿里云短信服务->下载阿里云短信发送demo(java版);
2>后端随机产生二维码,通过阿里云短信服务${code}进行发送
3>同时记录发送的code和客户端的手机号,存储在redis中,redis过期时间60秒;
4>用户注册提交将客户端手机号和验证码与redis中的key和value对比,存在则注册成功(同时删除redis对应缓存数据),不存在则返回;
如需询问 可加我QQ820688215
========================================================================================================
代码如下:
redis工具代码
maven:
<!--阿里云短信服务-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.6</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
<!--redis服务-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency> redis 服务类
public class RedisClientServer { private static final Logger logger = LoggerFactory.getLogger(RedisClientServer.class); private static JedisPool jedisPool = null; private static Jedis jedis = null; public static Jedis jedis_object = null; private static String host = "127.0.0.1";
private static String password = "123456";
private static Integer port = 6379; static{
if(jedisPool == null){
JedisPoolConfig config = new JedisPoolConfig();
//设置最大连接数
config.setMaxTotal(500);
//设置最大空闲数
config.setMaxIdle(20);
//设置最小空闲数
config.setMinIdle(8);
//设置超时时间
config.setMaxWaitMillis(3000);
//Idle时进行连接扫描
config.setTestWhileIdle(true);
//表示idle object evitor两次扫描之间要sleep的毫秒数
config.setTimeBetweenEvictionRunsMillis(30000);
//表示idle object evitor每次扫描的最多的对象数
config.setNumTestsPerEvictionRun(10);
//表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor
//扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
config.setMinEvictableIdleTimeMillis(60000);
//初始化连接池
jedisPool = new JedisPool(config, host, port);
jedis_object = new Jedis( host, port);
}
} private RedisClientServer() { } private static Jedis getJedisInstance(){ try {
if(null == jedis){
jedis = jedisPool.getResource();
jedis.auth(password);
}
} catch (Exception e) {
logger.error("实例化jedis失败.........", e);
}
return jedis;
} /**
* 向缓存中设置字符串内容
*@author liudianpeng.com
*@date
*/
public static boolean set(String key, String value) throws Exception {
Jedis jedis = null;
try {
jedis = getJedisInstance();
jedis.set(key, value);
return true;
} catch (Exception e) {
logger.error("redis set方法失败...key="+key+" value="+value, e);
} finally {
jedisPool.close();
}
return false;
} /**
* 向缓存中设置字符串内容 ,设置过期时间
*@author liudianpeng.com
*@date
*/
public static boolean set(String key, String value,Integer seconds) throws Exception {
Jedis jedis = null;
try {
jedis = getJedisInstance();
jedis.set(key, value);
jedis.expire(key, seconds);
return true;
} catch (Exception e) {
logger.error("redis set方法失败...key="+key+" value="+value, e);
} finally {
jedisPool.close();
}
return false;
} /**
* 根据key 获取内容
*@author liudianpeng.com
*@date
*/
public static Object get(String key) {
Jedis jedis = null;
try {
jedis = getJedisInstance();
Object value = jedis.get(key);
return value;
} catch (Exception e) {
logger.error("redis get方法失败...key="+key);
} finally {
jedisPool.close();
}
return null;
} /**
* 删除缓存中得对象,根据key
*@author liudianpeng.com
*@date
*/
public static boolean del(String key) {
Jedis jedis = null;
try {
jedis = getJedisInstance();
jedis.del(key);
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
jedisPool.close();
}
return false;
} /**
* 根据key 获取对象
*@author liudianpeng.com
*@date
*/
public static <T> T get(String key, Class<T> clazz) {
Jedis jedis = null;
try {
jedis = getJedisInstance();
String value = jedis.get(key);
return JSON.parseObject(value, clazz);
} catch (Exception e) {
e.printStackTrace();
} finally {
jedisPool.close();
}
return null;
} /**
* 设置key过期
*@author
*@date
*/
public static boolean expire(String key,int seconds){
Jedis jedis = null;
try {
jedis = getJedisInstance();
jedis.expire(key, seconds);
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
jedisPool.close();
}
return false;
} /**
* 判断是否存在key
*@author
*@date
*/
public static Boolean exists(String key){
Jedis jedis = null;
try {
jedis = getJedisInstance();
return jedis.exists(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}finally {
jedisPool.close();
}
} }
随机code生成工具
public class CoreUtils {
/**
* 生成随机字符串
*
* @param length
* @return
*/
public static String randomString(int length, boolean isNumeric) {
String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
if (isNumeric) {
base = "0123456789";
} Random random = new Random();
StringBuffer buffer = new StringBuffer(length);
for (int i = 0; i < length; i++) {
buffer.append(base.charAt(random.nextInt(base.length())));
} return buffer.toString();
} /**
* 不重复的参数进行拼装,返回查询条件字符串
*
* @param parameters 参数map
* @param sort 是否按照字典排序
* @return
*/
public static String generateQueryString(Map<String, Object> parameters, boolean sort) {
ArrayList<String> list = new ArrayList<String>();
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
// log.debug("参数:{}", entry.getKey());
if (!"".equals(entry.getValue())) {
list.add(entry.getKey() + "=" + entry.getValue());
}
} String[] arrayToSort = list.toArray(new String[list.size()]);
if (sort) {
Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
}
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
buffer.append(arrayToSort[i]);
if (i < (list.size() - 1)) {
buffer.append("&");
}
}
return buffer.toString();
} /**
* 根据参数获得相关签名
*
* @param buffer 加密参数,ASCII 码从小到大排序(字典序)
* @param encrypt 加密方式 SHA1 MD5
* @return
*/
public static String signature(String buffer, String encrypt, boolean toUpperCase) {
String sign = ""; if ("MD5".equals(encrypt)) {
// MD5加密
sign = Hashing.md5().hashString(buffer, Charsets.UTF_8).toString();
} else if ("SHA1".equals(encrypt)) {
// SHA1加密
sign = Hashing.sha1().hashString(buffer, Charsets.UTF_8).toString();
} if (toUpperCase) {
sign = sign.toUpperCase();
} return sign;
} /**
* 根据参数获得相关签名
*
* @param params 加密参数,ASCII 码从小到大排序(字典序)
* @param encrypt 加密方式 SHA1 MD5
* @return
*/
public static String signature(Map params, String encrypt, boolean toUpperCase) {
String sign = "";
// 拼接字符串,按照字典排序
String buffer = generateQueryString(params, true); // log.debug("待加密的字符串 => {}", buffer.toString());
if ("MD5".equals(encrypt)) {
// MD5加密
sign = Hashing.md5().hashString(buffer, Charsets.UTF_8).toString();
} else if ("SHA1".equals(encrypt)) {
// SHA1加密
sign = Hashing.sha1().hashString(buffer, Charsets.UTF_8).toString();
}
// log.debug("加密后的字符串 <=> {}", sign); if (toUpperCase) {
sign = sign.toUpperCase();
} return sign;
}
}
阿里云短信服务配置
/**
* SmsDemo 是官方demo
* 对其进行了修改,
* 1:sendMsg 发送短信消息给客户端,需要客户端传入手机号
*/
public class MessageUtils { /**
* 发送短信消息方法,返回验证码
* @param phone 用户手机号
* @return true 发送成功 ;false 发送失败
*/
public static Boolean sendMsg(String phone) throws Exception { //设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化ascClient需要的几个参数
final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
//替换成你的AK
final String accessKeyId = "";//你的accessKeyId,参考本文档步骤2
final String accessKeySecret = "";//你的accessKeySecret,参考本文档步骤2 //初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
SendSmsRequest request = new SendSmsRequest();
//使用post提交
request.setMethod(MethodType.POST);
//必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
request.setPhoneNumbers(phone);
//必填:短信签名-可在短信控制台中找到
request.setSignName("你的短信签名");
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode("SMS_0930219321");
String checkCode = CoreUtils.randomString(6, true);//此处是生成6位数验证码工具类
//request.setTemplateParam("{\"code\":\"123\"}");//测试用,此处json一定要严格按照json格式书写
request.setTemplateParam("{\"code\":\""+checkCode+"\"}");
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
//请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")){
//请求成功,短信已发送
//将手机号和生成的随机数存入redis 并设置redis的过期时间
RedisClientServer.set(phone,checkCode,60);
}
return sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK");
}
//测试发送短信
public static void main (String[] args) throws Exception { Boolean s = MessageUtils.sendMsg("13279879821");//手机号
System.out.println("=========="+s);
}
//客户端请求处理
//获取redis缓存中的手机号(key)和验证码(value):///////////////////////////
if ("".equals((RedisClientServer.get(dto.getMobile())).toString())||
null==(RedisClientServer.get(dto.getMobile())).toString()){
return Results.json().render("验证码已过期");
}else {
//删除缓存数据
RedisClientServer.del(dto.getMobile());
}