SpringBoot工程接入腾讯云短信服务平台

由于业务需要,需要使用第三方短信平台,进行验证码的发送。网上的短信服务平台主要由:百度、腾讯、阿里云;采用官方提供的SDK,调用接口即可。

腾讯云短信服务平台和阿里云短信服务平台,一般步骤为:注册--->企业/个人 实名认证----->创建应用----->创建短信签名------>创建模板---->等待审核---->使用提供的SDK调用接口,发送短信。

我使用的是腾讯云短信服务平台,阿里云的我进去之后和他的流程类似,这里直说腾讯云短信服务平台,注册完之后进去,首先会提示一个友好的提示界面,然后点击快速开始即可:

安装提示,一步一步会进入到认证界面,认证分为个人和企业,这里是给公司使用,我选择的是企业认证,然后选择已经完成企业认证的微信公众号认证(其他认证方式也阔以):

认证成功后,腾讯云短信平台会提示您的权限信息等,然后点击确定即可:

进行到这里,首先应该点击【应用管理】创建应用,这里使用默认的应用(系统给默认创建了一个,也可以自己创建);这里我使用默认的,所以,直接从【快速入门】,进行签名,模板的配置,然后等待审核结果,等审核通过,即可使用官方SDK调用API接口,发送短信:

点击应用可以查看应用的详细信息,

 其中SDK AppID,App Key 是需要你保密的,存放在你的服务器后台,调用短信API接口时,需要用到。

完成以上配置之后,下面就可以进行SpringBoot工程集成腾讯云短信SDK调用短信接口,发送验证码短信了。

第一步:pom.xml中,引入SDK

        <!-- 腾讯云sdk-->
		<dependency>
		    <groupId>com.github.qcloudsms</groupId>
		    <artifactId>qcloudsms</artifactId>
		    <version>1.0.6</version>
		</dependency>

第二步:创建短信验证码发送工具类

package com.inspur.tax.api.sms.utils;

import com.alibaba.fastjson.JSONObject;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.inspur.tax.api.sms.cache.CacheManagerImpl;
import org.json.JSONException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

public class SmsUtils {
    // 短信应用 SDK AppID
    private static int appid = 140******; // SDK AppID 以1400开头
    // 短信应用 SDK AppKey
    private static String appkey = "37b63******************3104399";
    // 短信模板 ID,需要在短信应用中申请
    private static int templateId = 6******; // NOTE: 这里的模板 ID`7839`只是示例,真实的模板 ID 需要在短信控制台中申请
    // 签名
    private static String smsSign = "中********平台"; // NOTE: 签名参数使用的是`签名内容`,而不是`签名ID`。这里的签名"腾讯云"只是示例,真实的签名需要在短信控制台申请

    static CacheManagerImpl cacheManagerImpl = new CacheManagerImpl();

    /**
     * 随机生成6位随机验证码
     * 方法说明
     * @Discription:扩展说明
     * @return
     * @return String
     */
    public static String createRandomVcode(){
        //验证码
        String vcode = "";
        for (int i = 0; i < 6; i++) {
            vcode = vcode + (int)(Math.random() * 9);
        }
        return vcode;
    }

    /*
     *发送手机验证码(30分钟)
     */
    public static boolean sendSms(String phoneNumber){
        try {
            String verifyCode = createRandomVcode();
            String[] params = {verifyCode,"10"};
            SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
            SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumber,
                    templateId, params, smsSign, "", "");
            System.out.println(result);
            if (result.result == 0) {
                //放入缓存 timeout为0一直保存
                cacheManagerImpl.putCache(phoneNumber, verifyCode + System.currentTimeMillis(), 0);
                return true;
            } else {
                return false;
            }
        } catch (HTTPException e) {
            // HTTP 响应码错误
            e.printStackTrace();
            return false;
        } catch (JSONException e) {
            // JSON 解析错误
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // 网络 IO 错误
            e.printStackTrace();
            return false;
        }
    }

    public static Map<String, Object> checkSms(String verifyCode, String phoneNumber) {
        Map<String, Object> result = new HashMap<String, Object>();
        String rtnCode = "";
        String rtnMsg = "";
        try{
            String verify = cacheManagerImpl.getCacheByKey(phoneNumber).getDatas().toString();
            if(!verify.substring(0,6).equals(verifyCode)){
                rtnCode = "-1";
                rtnMsg = "验证码错误";
                result.put("rtnCode", rtnCode);
                result.put("rtnMsg", rtnMsg);
                return result;
            }
            if((Double.parseDouble(verifyCode+System.currentTimeMillis()) - Double.parseDouble(verify)) > 1000*60*10){
                rtnCode = "-2";
                rtnMsg = "验证码过期";
                result.put("rtnCode", rtnCode);
                result.put("rtnMsg", rtnMsg);
                cacheManagerImpl.clearByKey(phoneNumber);
                return result;
            }
        }catch (NullPointerException e){
            rtnCode = "-1";
            rtnMsg = "手机号错误或验证码已被使用或验证码已过期移除";
            result.put("rtnCode", rtnCode);
            result.put("rtnMsg", rtnMsg);
            return result;
        }
        rtnCode = "0";
        rtnMsg = "验证通过";
        result.put("rtnCode", rtnCode);
        result.put("rtnMsg", rtnMsg);
        cacheManagerImpl.clearByKey(phoneNumber);
        return result;
    }
}

这里将发送给用户的短信验证码报错在缓存中,来进行验证码的验证,当然也可以将验证码报存在Session或者数据库中。

定义缓存操作接口,ICacheManager.java

package com.inspur.tax.api.sms.cache;

import java.util.Map;
import java.util.Set;

/*定义缓存操作接口,ICacheManager.java*/
public interface ICacheManager {
    /**
     * 存入缓存
     * @param key
     * @param cache
     */
    void putCache(String key, EntityCache cache);

    /**
     * 存入缓存
     * @param key
     * @param
     */
    void putCache(String key, Object datas, long timeOut);

    /**
     * 获取对应缓存
     * @param key
     * @return
     */
    EntityCache getCacheByKey(String key);

    /**
     * 获取对应缓存
     * @param key
     * @return
     */
    Object getCacheDataByKey(String key);

    /**
     * 获取所有缓存
     * @param
     * @return
     */
    Map<String, EntityCache> getCacheAll();

    /**
     * 判断是否在缓存中
     * @param key
     * @return
     */
    boolean isContains(String key);

    /**
     * 清除所有缓存
     */
    void clearAll();

    /**
     * 清除对应缓存
     * @param key
     */
    void clearByKey(String key);

    /**
     * 缓存是否超时失效
     * @param key
     * @return
     */
    boolean isTimeOut(String key);

    /**
     * 获取所有key
     * @return
     */
    Set<String> getAllKeys();
}

缓存类CacheManagerImpl

package com.inspur.tax.api.sms.cache;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/*实现接口ICacheManager,CacheManagerImpl.java
这里我使用了ConcurrentHashMap来保存缓存,本来以为这样就是线程安全的,
其实不然,在后面的测试中会发现它并不是线程安全的。*/
public class CacheManagerImpl  implements ICacheManager {
    private static Map<String, EntityCache> caches = new ConcurrentHashMap<String, EntityCache>();

    /**
     * 存入缓存
     * @param key
     * @param cache
     */
    public void putCache(String key, EntityCache cache) {
        caches.put(key, cache);
    }

    /**
     * 存入缓存
     * @param key
     * @param
     */
    public void putCache(String key, Object datas, long timeOut) {
        timeOut = timeOut > 0 ? timeOut : 0L;
        putCache(key, new EntityCache(datas, timeOut, System.currentTimeMillis()));
    }

    /**
     * 获取对应缓存
     * @param key
     * @return
     */
    public EntityCache getCacheByKey(String key) {
        if (this.isContains(key)) {
            return caches.get(key);
        }
        return null;
    }

    /**
     * 获取对应缓存
     * @param key
     * @return
     */
    public Object getCacheDataByKey(String key) {
        if (this.isContains(key)) {
            return caches.get(key).getDatas();
        }
        return null;
    }

    /**
     * 获取所有缓存
     * @param
     * @return
     */
    public Map<String, EntityCache> getCacheAll() {
        return caches;
    }

    /**
     * 判断是否在缓存中
     * @param key
     * @return
     */
    public boolean isContains(String key) {
        return caches.containsKey(key);
    }

    /**
     * 清除所有缓存
     */
    public void clearAll() {
        caches.clear();
    }

    /**
     * 清除对应缓存
     * @param key
     */
    public void clearByKey(String key) {
        if (this.isContains(key)) {
            caches.remove(key);
        }
    }

    /**
     * 缓存是否超时失效
     * @param key
     * @return
     */
    public boolean isTimeOut(String key) {
        if (!caches.containsKey(key)) {
            return true;
        }
        EntityCache cache = caches.get(key);
        long timeOut = cache.getTimeOut();
        long lastRefreshTime = cache.getLastRefeshTime();
        if (timeOut == 0 || System.currentTimeMillis() - lastRefreshTime >= timeOut) {
            return true;
        }
        return false;
    }

    /**
     * 获取所有key
     * @return
     */
    public Set<String> getAllKeys() {
        return caches.keySet();
    }
}

创建缓存对象EntityCache.java

package com.inspur.tax.api.sms.cache;

/*创建缓存对象EntityCache.java*/
public class EntityCache {
    /**
     * 保存的数据
     */
    private Object datas;

    /**
     * 设置数据失效时间,为0表示永不失效
     */
    private long timeOut;

    /**
     * 最后刷新时间
     */
    private long lastRefeshTime;

    public EntityCache(Object datas, long timeOut, long lastRefeshTime) {
        this.datas = datas;
        this.timeOut = timeOut;
        this.lastRefeshTime = lastRefeshTime;
    }
    public Object getDatas() {
        return datas;
    }
    public void setDatas(Object datas) {
        this.datas = datas;
    }
    public long getTimeOut() {
        return timeOut;
    }
    public void setTimeOut(long timeOut) {
        this.timeOut = timeOut;
    }
    public long getLastRefeshTime() {
        return lastRefeshTime;
    }
    public void setLastRefeshTime(long lastRefeshTime) {
        this.lastRefeshTime = lastRefeshTime;
    }
}

具体实现Service类:

package com.inspur.tax.api.sms.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.inspur.tax.api.common.Result;
import com.inspur.tax.api.common.Ywlx;
import com.inspur.tax.api.common.entity.TransEntity;
import com.inspur.tax.api.sms.cache.CacheManagerImpl;
import com.inspur.tax.api.sms.service.ISmsSendService;
import com.inspur.tax.api.sms.utils.SmsUtils;
import com.inspur.tax.constat.ResultEnum;
import com.inspur.tax.exception.JkjhException;
import com.inspur.tax.utils.FastJsonUtils;

import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

@Service
public class SmsSendServiceImpl implements  ISmsSendService{

	@Override
	public TransEntity<?> process(TransEntity<?> trans) {
		Map<String,Object> business = new HashMap<String,Object>();
		try {
			String ywlx = trans.getComment().getYwlx();
			Map<String,Object> param =  FastJsonUtils.stringToCollect(String.valueOf(trans.getBusiness()));
		
			if(Ywlx.SMS_SEND.getCode().equals(ywlx)) {//发送短信验证码
				business = sendSms(param);
			}else if(Ywlx.SMS_CHECK.getCode().equals(ywlx)) {//验证短信验证码
				business = checkSms(param);
			}
			
			trans = TransEntity.setResult(ResultEnum.YHZX_success).change(trans).data(business);
			
		}catch(Exception e) {
			throw new JkjhException(Result.SYS_ERROR,trans);
		}finally {
			return trans;
		}
	}

	@Override
	public boolean isSupport(String ywlx) {
		// TODO Auto-generated method stub
		return (Ywlx.SMS_SEND.getCode().equals(ywlx) ||
				Ywlx.SMS_CHECK.getCode().equals(ywlx) );
	}
	
    public Map<String, Object> sendSms(Map<String, Object> params){
        Map<String, Object> result = new HashMap<String, Object>();
        String rtnCode = "";
        String rtnMsg = "";
        String phoneNumber = String.valueOf(params.get("phoneNumber"));
        boolean bool = SmsUtils.sendSms(phoneNumber);
        if(bool){
            rtnCode = "0";
            rtnMsg = "验证码发送成功";
        } else {
            rtnCode = "-3";
            rtnMsg = "验证码发送失败";
        }
        result.put("rtnCode", rtnCode);
        result.put("rtnMsg", rtnMsg);
        return result;
    }

   
    public Map<String, Object> checkSms( Map<String, Object> params){
        String phoneNumber = String.valueOf(params.get("phoneNumber"));
        String verifyCode = String.valueOf(params.get("verifyCode"));
        Map<String, Object> result = SmsUtils.checkSms(verifyCode, phoneNumber);
        return result;
    }

	
}

参考博客:https://blog.csdn.net/weixin_41843757/article/details/100141677

 

 

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李晓LOVE向阳

你的鼓励是我持续的不断动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值