怎么使用Java第三方实现发送短信功能

寻技术 JAVA编程 2023年07月11日 122

本文小编为大家详细介绍“怎么使用Java第三方实现发送短信功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么使用Java第三方实现发送短信功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    一、介绍

    在项目开发中,短信发送功能在很多地方都用得到,例如:通知短信、验证码、营销短信、推广短信等等,近期阿里云等云服务商的短信服务针对个人用户不友好(需求企业资质),现在给大家介绍一款的产品:乐讯通,针对个人用户较为友好,可以很便捷的进行开发测试。

    二、使用步骤

    1. 平台注册

    使用手机号注册即可。

    注意:注册成功后,默认密码就是手机号。
    可在 “系统管理”->"密码管理"中进行密码的修改 。

    2. 短信签名和短信模板

    平时比较常见的验证码短信格式为:

    【码赛客1024】:注册验证码为312562,请勿泄露给他人。

    前面括号中的就是短信签名,后边部分就是短信模板,因此可以分析出格式为:
    【短信签名】:短信模板。

    2.1 设置签名
    文字短信 -> 短信设置 -> 签名管理 -> 添加新的签名

    2.2 设置模板
    文字短信 -> 短信设置 -> 签名管理 -> 添加新的模板

    模板设置需要注意的是,模板中使用{}作为占位符,例如:
    【短信签名】:注册验证码为{s6},请勿泄露给他人。
    其中的{s6}会被替换为验证码,而6指的是字符最大长度,超过则无法发送。

    3. 基于官方API文档实现短信发送

    3.1 官方demo

    API文档 -> 开发引导 -> 代码示例 -> Java ,代码如下

    package com.ljs;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.Console;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.lang.reflect.MalformedParameterizedTypeException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.security.MessageDigest;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Calendar;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.List;
    import java.util.ListIterator;
    import java.util.Map;
    import java.util.Set;
    import java.util.TreeMap;
    
    import javax.lang.model.element.VariableElement;
    import javax.management.monitor.MonitorSettingException;
    import javax.print.attribute.standard.DateTimeAtCompleted;
    
    import org.junit.Test;
    
    public class MyTest {
        public static void main(String[] args) throws ParseException {
        	//时间戳
            long timestamp = System.currentTimeMillis();
            System.out.println(timestamp);
            //url
            String url = "http://www.lokapi.cn/smsUTF8.aspx"; 
            //签名,在发送时使用md5加密
            String beforSign = "action=sendtemplate&username=18586975869&password="+getMD5String("18586975869")+"&token=389c1a49&timestamp="+timestamp;
            //参数串
            String postData = "action=sendtemplate&username=18586975869&password="+getMD5String("18586975869")+"&token=389c1a49&templateid=CF2D56FC&param=18586975869|666666&rece=json&timestamp="+timestamp+"&sign="+getMD5String(beforSign);
            //调用其提供的发送短信方法
            String result = sendPost(url,postData); 
            System.out.println(result);
        }  
        //发送短信的方法
        public static String sendPost(String url, String param) {
            PrintWriter out = null;
            BufferedReader in = null;
            String result = "";
            try {
                URL realUrl = new URL(url);
                // 打开和URL之间的连接
                URLConnection conn = realUrl.openConnection();
                // 设置通用的请求属性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent",
                        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 发送POST请求必须设置如下两行
                conn.setDoOutput(true);
                conn.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                out = new PrintWriter(conn.getOutputStream());
                // 发送请求参数
                out.print(param);
                // flush输出流的缓冲
                out.flush();
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(
                        new InputStreamReader(conn.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("发送 POST 请求出现异常!"+e);
                e.printStackTrace();
            }finally{ //使用finally块来关闭输出流、输入流
                try{
                    if(out!=null){
                        out.close();
                    }
                    if(in!=null){
                        in.close();
                    }
                }
                catch(IOException ex){
                    ex.printStackTrace();
                }
            }
            return result;
        }  
        //用来计算MD5的函数  
        public static String getMD5String(String rawString){    
            String[] hexArray = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
            try{
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(rawString.getBytes());
                byte[] rawBit = md.digest();
                String outputMD5 = " ";
                for(int i = 0; i<16; i++){
                    outputMD5 = outputMD5+hexArray[rawBit[i]>>>4& 0x0f];
                    outputMD5 = outputMD5+hexArray[rawBit[i]& 0x0f];
                }
                return outputMD5.trim();
            }catch(Exception e){
                System.out.println("计算MD5值发生错误");
                e.printStackTrace();
            }
            return null;
        }
        /**
         * 生成秘钥
         * 
         * @param tm
         * @param key
         * @return
         */
        public static String createSign(TreeMap<String, String> tm, String key) {
            StringBuffer buf = new StringBuffer(key);
            for (Map.Entry<String, String> en : tm.entrySet()) {
                String name = en.getKey();
                String value = en.getValue();
                if (!"sign".equals(name) && !"param".equals(name) && value != null && value.length() > 0 && !"null".equals(value)) {
                    buf.append(name).append('=').append(value).append('&');
                }
            }
            String _buf = buf.toString();
            return _buf.substring(0, _buf.length() - 1);
        }
    
        /**
          * 将文件转成base64 字符串
          * @param path文件路径
          * @return  * 
          * @throws Exception
          */
         public static String encodeBase64File(String path) throws Exception {
              File file = new File(path);;
              FileInputStream inputFile = new FileInputStream(file);
              byte[] buffer = new byte[(int) file.length()];
              inputFile.read(buffer);
              inputFile.close();
              //return new BASE64Encoder().encode(buffer);
    		  return "";
         }
    }

    3.2 文字短信-模板发送

    1.请求地址,UTF8编码请求地址:

    http://www.lokapi.cn/smsUTF8.aspx

    2.请求协议:
    http

    3.请求方式:采用
    post方式
    提交请求
    4.请求报文:
    action=sendtemplate&username=zhangsan&password=E10ADC3949BA59ABBE56E057F20F883E&token=894gbhy&templateid=638fgths&param=手机号1|参数1|参数2@手机号2|参数1|参数2&rece=json&timestamp=636949832321055780&sign=96E79218965EB72C92A54

    5.参数说明
    参数名称 是否必须 描述 示例
    action 操作类型 (固定值)action=sendtemplate
    username 账户名 username=zhangsan
    password 账户密码,密码必须MD5加密并且取32位大写 password=E10ADC3949BA59ABBE56E057F20F883E
    token 产品总览页面对应产品的Token token=894gbhy
    templateid 模板管理报备的模板ID templateid=638fgths
    param 发送参数,可发送一个或多个手机号,建议单次提交最多5000个号码 17712345678|张三|2541@13825254141|李四|2536
    dstime 设置要发送短信的时间,精确到秒(yyyy-MM-dd HH:mm:ss) 2017-01-05 16:23:23
    rece 返回类型json、xml,默认(json) rece=json
    timestamp 时间戳,13位时间戳,单位(毫秒) timestamp=636949832321055780
    sign 签名校验 sign=96E79218965EB72C92A54

    param参数详细说明

    发送一个手机号模板为【手机号1|参数1|参数2】
    发送多个手机号模板为【手机号1|参数1|参数2@手机号2|参数3|参数4@&hellip;】
    第一列必须为手机号,参数1,参数2对应短信模板里的参数顺序,英文竖线隔开, 比如短信模板为【签名】您好,{s6},您的验证码是:{s6},参数1就对应您好后边的{s6},参数2对应验证码是后边的{s6}, 多个手机号以@隔开。

    若模板内没有参数则只输入手机号即可。

    sign参数详细说明

    签名由参数action,username,password,token,timestamp进行MD5加密组成
    比如这些值拼接后为action=sendtemplate&username=zhangsan&password=E10ADC3949BA59ABBE56E057F20F883E&token=588aaaaa&timestamp=636949832321055780,那么就MD5加密这个参数字符串得到结果后作为sign的值sign=96E79218965EB72C92A54

    基于官方java代码和参数说明,替换自己的值,即可实现发送。

    6.返回结果

    //成功返回
    {
        "returnstatus":"success",
        "code":"0",
        "taskID":[
            {
                "tel_17712345678":"15913494519502337"
            }
        ]
    }
    //失败返回
    {
        "returnstatus":"error",
        "code":"-51",
        "remark":"访问超时!"
    }

    三、封装发送短信工具类

    1.添加 fastjson 的依赖,用于把返回结果转为对象,方便处理。

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.75</version>
    </dependency>

    2.工具类如下

    public class SendSMSUtil {
        /**
         * 封装的发验证码的方法
         * @param account 平台账户
         * @param password 平台密码
         * @param token 平台token
         * @param templateid 短信模板id
         * @param phone 短信接收方手机号
         * @param code  验证码
         * @return
         */
        public static MsgResult sendMsgPost(String account,String password,String token,String templateid,String phone,String code){
            //时间戳
            long timestamp = System.currentTimeMillis();
            //System.out.println(timestamp);
            //url
            String url = "http://www.lokapi.cn/smsUTF8.aspx";
            //签名
            String beforSign = "action=sendtemplate&username="+account+"&password="+getMD5String(password)+"&token="+token+"&timestamp="+timestamp;
            //参数串
            String postData = "action=sendtemplate&username="+account+"&password="+getMD5String(password)+"&token="+token+"&templateid="+templateid+"&param="+phone+"|"+code+"&rece=json&timestamp="+timestamp+"&sign="+getMD5String(beforSign);
            //发送请求
            String result = sendPost(url,postData);
            //将json结果转为对象,方便判断
            MsgResult msgResult = JSON.parseObject(result, MsgResult.class);
            return msgResult;
        }
        //原本的发送方法
        public static String sendPost(String url, String param) {
            PrintWriter out = null;
            BufferedReader in = null;
            String result = "";
            try {
                URL realUrl = new URL(url);
                // 打开和URL之间的连接
                URLConnection conn = realUrl.openConnection();
                // 设置通用的请求属性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 发送POST请求必须设置如下两行
                conn.setDoOutput(true);
                conn.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                out = new PrintWriter(conn.getOutputStream());
                // 发送请求参数
                out.print(param);
                // flush输出流的缓冲
                out.flush();
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("发送 POST 请求出现异常!"+e);
                e.printStackTrace();
            } finally{  //使用finally块来关闭输出流、输入流
                try{
                    if(out!=null){
                        out.close();
                    }
                    if(in!=null){
                        in.close();
                    }
                }
                catch(IOException ex){
                    ex.printStackTrace();
                }
            }
            return result;
        }
    
        //用来计算MD5的函数
        public static String getMD5String(String rawString){
            String[] hexArray = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
            try{
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(rawString.getBytes());
                byte[] rawBit = md.digest();
                String outputMD5 = " ";
                for(int i = 0; i<16; i++){
                    outputMD5 = outputMD5+hexArray[rawBit[i]>>>4& 0x0f];
                    outputMD5 = outputMD5+hexArray[rawBit[i]& 0x0f];
                }
                return outputMD5.trim();
            }catch(Exception e){
                System.out.println("计算MD5值发生错误");
                e.printStackTrace();
            }
            return null;
        }
    }

    用于接收返回值的对象

    public class MsgResult{
        //返回描述
        private String returnstatus;
        //返回状态码
        private Integer code;
        //错误消息
        private String remark;
    
        public String getReturnstatus() {
            return returnstatus;
        }
    
        public void setReturnstatus(String returnstatus) {
            this.returnstatus = returnstatus;
        }
    
        public Integer getCode() {
            return code;
        }
    
        public void setCode(Integer code) {
            this.code = code;
        }
    
        public String getRemark() {
            return remark;
        }
    
        public void setRemark(String remark) {
            this.remark = remark;
        }
    
        @Override
        public String toString() {
            return "MsgResult{" +
                    "returnstatus='" + returnstatus + ''' +
                    ", code=" + code +
                    ", remark='" + remark + ''' +
                    '}';
        }
    }

    3.调用测试

    public class SendSMSTest {
        public static void main(String[] args) throws ParseException {
        	//使用工具类发送短信,返回封装的对象
            MsgResult msgResult = SendSMSUtil.sendMsgPost("平台账号","平台密码","token","短信模板id","接受方手机号","验证码");
            //进行判断
            if("success".equals(msgResult.getReturnstatus()) && msgResult.getCode()==0){
                System.out.println("发送成功");
            }else{
                System.out.println("发送失败,原因是:"+msgResult.getRemark());
            }
        }
    }
    关闭

    用微信“扫一扫”