阿里云和聚合的短信服务

一.阿里云的oss

阿里云短信验证

开通阿里云短信服务

记得保存创建完用户生成的accsddkey和id

##1.4编写代码

查看sdk的java版本

使用步骤:

1.4.1 导入依赖(得是在springboot下)


<dependencies>
<!-- 阿里云的短信服务-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.3</version>
</dependency>
<!-- 使用json字符串-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<!-- 因为验证码需要几分钟过期,整合redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
②测试一下
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 是为了DateTime-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.1</version>
</dependency>

1.4.2 入依赖(得是在springboot下)

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
@RunWith(SpringRunner.class)
@SpringBootTest
结果
public class DemoTest {
@Test
public void contextLoads(){
//连接阿里云
//regionId不要动
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
"LTAI4G8jAHLW62M5cPq5UWn2", "gt4N0G1Sp86o1QejDDfHNXv69fOEmQ");
IAcsClient client = new DefaultAcsClient(profile);
//构建请求
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com"); //不要动
request.setSysVersion("2017-05-25"); //不要动
request.setSysAction("SendSms");
//自定义名称(手机号,验证码,签名,模板!)
request.putQueryParameter("PhoneNumbers", "18879493586");
request.putQueryParameter("SignName", "传智播客");
request.putQueryParameter("TemplateCode", "SMS_199221156");
//构建短信验证码,先写死
HashMap<String, Object> map = new HashMap<>();
map.put("code",2233);
request.putQueryParameter("TemplateParam",
JSONObject.toJSONString(map));
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
}

###1.4.3 实际是写一个微服务的接口-------其实就是一个控制器类
####在service接口

import java.util.Map;
public interface SendSMS {
/*
* 参数一:接受短信的电话号码
* 参数二:模板
* 参数三:验证码
* */
public boolean send(String phoneNumber, String templateCode,
Map<String,Object> cod);
}

实现类

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.liangchao.service.SendSMS;
import java.util.HashMap;
import java.util.Map;
@Service
public class SendSMSImpl implements SendSMS {
@Override
public boolean send(String phoneNumber, String templateCode, Map<String,
Object> cod) {
//连接阿里云
//regionId不要动
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
"LTAI4G8jAHLW62M5cPq5UWn2", "gt4N0G1Sp86o1QejDDfHNXv69fOEmQ");
IAcsClient client = new DefaultAcsClient(profile);
//构建请求
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com"); //不要动
request.setSysVersion("2017-05-25"); //不要动
request.setSysAction("SendSms");
在controller-------------这才是提供给外面的接口
//自定义名称(手机号,验证码,签名,模板!)
//这儿的参数名称一定是这样写,不能写成其他的名字
request.putQueryParameter("PhoneNumbers", phoneNumber);
request.putQueryParameter("SignName", "传智播客");
request.putQueryParameter("TemplateCode", templateCode);
//验证码
request.putQueryParameter("TemplateParam",
JSONObject.toJSONString(cod));
try {
CommonResponse response = client.getCommonResponse(request);
//返回的短信信息在控制台
System.out.println(response.getData());
//发送成功
return response.getHttpResponse().isSuccess();
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
//发送失败
return false;
}
}

在controller

import com.liangchao.service.SendSMS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@CrossOrigin //跨域支持
public class SendSMSController {

@Autowired
private SendSMS sendSMS;

@Autowired
配置环境application.properties,启动reids
测试
先启动redis吗,再启动启动类,再发送请求 http://localhost:9090/send/18879493586
private StringRedisTemplate<String,String> redisTemplate;

@GetMapping("/send/{phone}")
public String sendsms(@PathVariable("phone") String phone){
	//调用方法发送(模拟真实业务)
	//从redis缓存中获得数据
	String code = redisTemplate.opsForValue().get(phone);
	//判断code是否拿到数据了,也就是是否在redis有缓存
	if (!StringUtils.isEmpty(code)){
		return phone+ ":" +code + "已近存在,没过期";
	}
	//生成验证码并且存储到redis中
	//String code = RandomStringUtils.randomNumeric(4);
	code = UUID.randomUUID().toString().substring(0, 4);
	HashMap<String, Object> map = new HashMap<String, Object>();
	map.put("code",code);
	//发验证码短信
	boolean isSend = sendSMS.send(phone, "SMS_199221156", map);
	if (isSend){
		//把这条数据放入到redis中
		//过期时间 5s
		redisTemplate.opsForValue().set(phone,code,5, TimeUnit.SECONDS);
		return phone+ ":" +code + "发送成功";
	}else {
		return "发送失败";
	}
}
}

配置环境application.properties,启动reids

server.port=9090
spring.redis.host=127.0.0.1
spring.redis.port=6379

测试;先启动redis吗,再启动启动类,再发送请求 http://localhost:9090/send/18879493586

1.5 拓展:批量短息发送

<!-- 阿里云的短信服务-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.3</version>
</dependency>
<!-- 批量发送短信-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
<!-- 使用json字符串-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<!-- 因为验证码需要几分钟过期,整合redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendBatchSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendBatchSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.liangchao.UserApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = UserApplication.class)
public class DemoTest {
@Test
public void contextLoads(){
//连接阿里云
//regionId不要动
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
"LTAI4G8jAHLW62M5cPq5UWn2", "gt4N0G1Sp86o1QejDDfHNXv69fOEmQ");
IAcsClient client = new DefaultAcsClient(profile);
//构建请求
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com"); //不要动
request.setSysVersion("2017-05-25"); //不要动
request.setSysAction("SendSms");
//自定义名称(手机号,验证码,签名,模板!)
request.putQueryParameter("PhoneNumbers", "18879493586");
request.putQueryParameter("SignName", "传智播客");
request.putQueryParameter("TemplateCode", "SMS_199221156");
//构建短信验证码,先写死
HashMap<String, Object> map = new HashMap<>();
map.put("code",2233);
request.putQueryParameter("TemplateParam",
JSONObject.toJSONString(map));
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
@Test
public void sendBuckMessage(){
//设置超时时间-可自行调整
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 = "LTAI4G8jAHLW62M5cPq5UWn2";//你的accessKeyId,参
考本文档步骤2
final String accessKeySecret = "gt4N0G1Sp86o1QejDDfHNXv69fOEmQ";//你的
accessKeySecret,参考本文档步骤2
//初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou",
accessKeyId,
accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
SendBatchSmsRequest request = new SendBatchSmsRequest();
//使用post提交
request.setSysMethod(MethodType.POST);
//必填:待发送手机号。支持JSON格式的批量调用,批量上限为100个手机号码,批量调用相对于单
条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
request.setPhoneNumberJson("18879493586");
//必填:短信签名-支持不同的号码发送不同的短信签名
request.setSignNameJson("传智播客");
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode("SMS_199221156");
//必填:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此
处的值为
//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包
含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
request.setTemplateParamJson("[{\"name\":\"Tom\", \"code\":\"123\"},
{\"name\":\"Jack\", \"code\":\"456\"}]");
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCodeJson("[\"90997\",\"90998\"]");
//请求失败这里会抛ClientException异常
SendBatchSmsResponse sendSmsResponse = null;
try {
sendSmsResponse = acsClient.getAcsResponse(request);
} catch (ClientException e) {
e.printStackTrace();
}
if(sendSmsResponse.getCode() != null &&
sendSmsResponse.getCode().equals("OK")) {
//请求成功
}
}
}

短信工具类

public class AliyunSmsUtil {
	private static final Logger logger = LoggerFactory.getLogger(AliyunSmsUtil.class);

	public final static String accessKeyId = "LTAI5t7FB61cmLdekJYwcBBP";//你的accessKeyId,参考本文档步骤2
	public final static String accessKeySecret = "ue3ZMIuBjrzGDMwHnfPYGILM61artV";//你的accessKeySecret,参考本文档步骤2

	//短信模板
	public final static String TPL_CODE_VALID = "SMS_219905052"; //验证码
	/**
	 * 发送短信验证码
	 * @param tel
	 * @param code
	 * @return
	 */
	public static String sendCheckSMSCode(String tel, String code) {
		return sendSms(tel, TPL_CODE_VALID, "{ \"code\":\""+code+"\"}");
	}

	/**
	 * 发送短信
	 * @param tel 手机号
	 * @param templateCode 模板code
	 * @return
	 */
	public static String sendSms(String tel, String templateCode){
		return sendSms(tel, templateCode,null);
	}

	/**
	 * 发送短信
	 * @param tel 手机号
	 * @param templateCode 模板code
	 * @param templateParam 模板参数
	 * @return
	 */
	public static String sendSms(String tel, String templateCode, String templateParam){

		DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",accessKeyId , accessKeySecret);
		IAcsClient client = new DefaultAcsClient(profile);

		CommonRequest request = new CommonRequest();
		request.setSysMethod(MethodType.POST);
		request.setSysDomain("dysmsapi.aliyuncs.com");
		request.setSysVersion("2017-05-25");
		request.setSysAction("SendSms");
		request.putQueryParameter("PhoneNumbers", tel);
		request.putQueryParameter("SignName", "友桔");
		request.putQueryParameter("TemplateCode", templateCode);
		request.putQueryParameter("TemplateParam", templateParam);
		try {
			CommonResponse response = client.getCommonResponse(request);
			Map<String,String> map=JsonUtils.fromJson(response.getData());
			return map.get("Code");
		} catch (ServerException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			e.printStackTrace();
		}
		return  null;
	}

	
}

二.聚合数据

前期准备工作:

  • 只对实名认证的企业用户开放该服务;
  • 申请接口,你可以在个人中心 ➡️ 数据中心 ➡️ 我的API 模块看到此接口的调用凭证请求key
  • 购买数据的请求次数(免费和有赠送次数的接口可以先行调试)
  • 您必须在聚合官网的个人中心里面提前申请短信模板,待客服审核通过后才能调用接口

接口文档:https://www.juhe.cn/docs/api/id/54/aid/121

参数说明

参数名 必填 类型 说明
mobile String 接受短信的手机号
tpl_id int 短信模板id
key String 申请的请求key
tpl_value false String 模板变量,根据模板中变量决定,可为空
dtype false String 返回的数据格式,xml或者json,默认json

maven依赖

	<dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.2.3</version>
            <classifier>jdk15</classifier>
        </dependency>

代码:

package cn.juhe.demo;


import net.sf.json.JSONObject;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

/**
 * @Author: micro cloud fly
 * @Description: 短信API的调用示例
 * @Date: Created in 1:45 下午 2020/10/9
 */
public class Demo54 {
    //接口请求地址
    public static final String URL = "http://v.juhe.cn/sms/send?mobile=%s&tpl_id=%s&tpl_value=%s&key=%s";
    //申请接口的请求key
    // TODO: 您需要改为自己的请求key
    public static final String KEY = "您需要改为自己的请求key";
    //此次发送短信需要使用的短信模板
    //3010模板对应的发送内容为:【聚合数据1】您的验证码是#code#.你还剩余次数#total#,如非本人操作,请忽略本短信
    //其中#code#是短信模板中的变量,用于开发者动态生成验证码
    //在运行代码的时候您需要改为自己拥有的模板
    // TODO: 您需要改为自己的模板id
    public static final int TPL_ID = 3010;

    public static void main(String[] args) {
        //用于接收短信的手机号码,你需要修改此处
        // TODO: 改为自己手机号测试看看
        String mobile = "17715******77";
        //短信模板中的您自定义的变量
        // TODO: 改为您模板中的需要的变量
        String variable = "#code#=12345&#total#=100";
        print(mobile, variable);
    }

    /**
     * 打印请求结果
     *
     * @param mobile   手机号
     * @param variable 模板变量
     */
    public static void print(String mobile, String variable) {
        //发送http请求的url
        String url = null;
        try {
            url = String.format(URL, mobile, TPL_ID, URLEncoder.encode(variable, "utf-8"), KEY);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String response = doGet(url);
        System.out.println(response);
        try {
            JSONObject jsonObject = JSONObject.fromObject(response);
            int error_code = jsonObject.getInt("error_code");
            if (error_code == 0) {
                System.out.println("调用接口成功");
                JSONObject result = jsonObject.getJSONObject("result");
                String sid = result.getString("sid");
                int fee = result.getInt("fee");
                System.out.println("本次发送的唯一标示:" + sid);
                System.out.println("本次发送消耗的次数:" + fee);
            }else{
                System.out.println("调用接口失败:"+ jsonObject.getString("reason"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * get方式的http请求
     *
     * @param httpUrl 请求地址
     * @return 返回结果
     */
    public static String doGet(String httpUrl) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式:get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 发送请求
            connection.connect();
            // 通过connection连接,获取输入流
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 封装输入流,并指定字符集
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                // 存放数据
                StringBuilder sbf = new StringBuilder();
                String temp;
                while ((temp = bufferedReader.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();// 关闭远程连接
            }
        }
        return result;
    }


    /**
     * post方式的http请求
     *
     * @param httpUrl 请求地址
     * @param param   请求参数
     * @return 返回结果
     */
    public static String doPost(String httpUrl, String param) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);
            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 通过连接对象获取一个输出流
            outputStream = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            outputStream.write(param.getBytes());
            // 通过连接对象获取一个输入流,向远程读取
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                StringBuilder sbf = new StringBuilder();
                String temp;
                // 循环遍历一行一行读取数据
                while ((temp = bufferedReader.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/LC_Liangchao/article/details/121833300