Java 实现发送短信 短信API调用

在项目开发中,基本上离不开短信使用。如:验证码,语音验证码,订单通知,物流通知,会员通知,交易通知,变更通知等等。笔者也使用过很多平台,个人感觉摩杜云还是不错的。该平台除了支持全球280多个地区发送外,还支持区块链,交易所,金融等行业发送。此处就不在赘述了。

1.当然是到摩杜云注册个账号。

2.登录后台右上角点击accesskey进去创建accesskey、secretkey。

3.准备json_jdk1.7.jar(当然可以下载最新版的,情况根据自己需要。)

4.SmsSDKDemo.java

package com.moduyun.sdk.sms;

import com.moduyun.sdk.sms.yun.SmsSingleSender;
import com.moduyun.sdk.sms.yun.SmsSingleSenderResult;

public class SmsSDKDemo {
    public static void main(String[] args) {
    	try {
    		//请根据实际 accesskey 和 secretkey 进行开发,以下只作为演示 sdk 使用
    		String accesskey = "xxx";
    		String secretkey ="xxxxx";
    		//手机号码
    		String phoneNumber = "136252412xx";
    		 //初始化单发
	    	SmsSingleSender singleSender = new SmsSingleSender(accesskey, secretkey);
	    	SmsSingleSenderResult singleSenderResult;
	         String msg = "【摩杜云】尊敬的用户:您的验证码:123456,工作人员不会索取,请勿泄漏。";
	    	 //普通单发,注意前面必须为【】符号包含,置于头或者尾部。
	    singleSenderResult = singleSender.send(0, "86", phoneNumber, msg, "", "");
	    	System.out.println(singleSenderResult);
	    	
	    	

    	} catch (Exception e) {
			e.printStackTrace();
		}
    }
}

5.SmsSenderUtil.java

package com.moduyun.sdk.sms.yun;

import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Random;

import org.json.JSONArray;
import org.json.JSONObject;

class SmsSenderUtil {

    protected Random random = new Random();
    
    public String stringMD5(String input) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        byte[] inputByteArray = input.getBytes();
        messageDigest.update(inputByteArray);
        byte[] resultByteArray = messageDigest.digest();
        return byteArrayToHex(resultByteArray);
    }
    
    protected String strToHash(String str) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        byte[] inputByteArray = str.getBytes();
        messageDigest.update(inputByteArray);
        byte[] resultByteArray = messageDigest.digest();
        return byteArrayToHex(resultByteArray);
    }

    public String byteArrayToHex(byte[] byteArray) {
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] resultCharArray = new char[byteArray.length * 2];
        int index = 0;
        for (byte b : byteArray) {
            resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
            resultCharArray[index++] = hexDigits[b & 0xf];
        }
        return new String(resultCharArray);
    }
    
    public int getRandom() {
    	return random.nextInt(999999)%900000+100000;
    }
    
    public HttpURLConnection getPostHttpConn(String url) throws Exception {
        URL object = new URL(url);
        HttpURLConnection conn;
        conn = (HttpURLConnection) object.openConnection();
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestMethod("POST");
        return conn;
	}
    
    public String calculateSig(
    		String accesskey,
    		long random,
    		String msg,
    		long curTime,    		
    		ArrayList<String> phoneNumbers) throws NoSuchAlgorithmException {
        String phoneNumbersString = phoneNumbers.get(0);
        for (int i = 1; i < phoneNumbers.size(); i++) {
            phoneNumbersString += "," + phoneNumbers.get(i);
        }
        return strToHash(String.format(
        		"accesskey=%s&random=%d&time=%d&mobile=%s",
        		accesskey, random, curTime, phoneNumbersString));
    }
    
    public String calculateSigForTempl(
    		String accesskey,
    		long random,
    		long curTime,    		
    		ArrayList<String> phoneNumbers) throws NoSuchAlgorithmException {
        String phoneNumbersString = phoneNumbers.get(0);
        for (int i = 1; i < phoneNumbers.size(); i++) {
            phoneNumbersString += "," + phoneNumbers.get(i);
        }
        return strToHash(String.format(
        		"accesskey=%s&random=%d&time=%d&mobile=%s",
        		accesskey, random, curTime, phoneNumbersString));
    }
    
    public String calculateSigForTempl(
    		String accesskey,
    		long random,
    		long curTime,    		
    		String phoneNumber) throws NoSuchAlgorithmException {
    	ArrayList<String> phoneNumbers = new ArrayList<>();
    	phoneNumbers.add(phoneNumber);
    	return calculateSigForTempl(accesskey, random, curTime, phoneNumbers);
    }
    
    public JSONArray phoneNumbersToJSONArray(String nationCode, ArrayList<String> phoneNumbers) {
        JSONArray tel = new JSONArray();
        int i = 0;
        do {
            JSONObject telElement = new JSONObject();
            telElement.put("nationcode", nationCode);
            telElement.put("mobile", phoneNumbers.get(i));
            tel.put(telElement);
        } while (++i < phoneNumbers.size());

        return tel;
    }
    
    public JSONArray smsParamsToJSONArray(ArrayList<String> params) {
        JSONArray smsParams = new JSONArray();        
        for (int i = 0; i < params.size(); i++) {
        	smsParams.put(params.get(i));	
		}
        return smsParams;
    }
    
    public SmsSingleSenderResult jsonToSmsSingleSenderResult(JSONObject json) {
    	SmsSingleSenderResult result = new SmsSingleSenderResult();
    	
    	result.result = json.getInt("result");
    	result.errMsg = json.getString("errmsg");
    	if (0 == result.result) {
	    	result.ext = json.getString("ext");
	    	result.sid = json.getString("sid");
	    	result.fee = json.getInt("fee");
    	}
    	return result;
    }

    public SmsStatusPullCallbackResult jsonToSmsStatusPullCallbackrResult(JSONObject json) {
    	SmsStatusPullCallbackResult result = new SmsStatusPullCallbackResult();
    	
    	result.result = json.getInt("result");
    	result.errmsg = json.getString("errmsg");    	
    	if (true == json.isNull("data")) {
    		return result;
    	}
    	result.callbacks = new ArrayList<>();  
    	JSONArray datas  = json.getJSONArray("data");
    	for(int index = 0 ; index< datas.length(); index++){
    			JSONObject cb = datas.getJSONObject(index);
    			SmsStatusPullCallbackResult.Callback callback = result.new Callback();
    			callback.user_receive_time = cb.getString("user_receive_time");
    			callback.nationcode = cb.getString("nationcode");
    			callback.mobile = cb.getString("mobile");
    			callback.report_status = cb.getString("report_status");
    			callback.errmsg = cb.getString("errmsg");
    			callback.description = cb.getString("description");
    			callback.sid = cb.getString("sid");
    			result.callbacks.add(callback);
    	}
    	return result;
    }
    
    public SmsVoiceVerifyCodeSenderResult jsonToSmsSingleVoiceSenderResult(JSONObject json) {
    	SmsVoiceVerifyCodeSenderResult result = new SmsVoiceVerifyCodeSenderResult();
    	result.result = json.getInt("result");
    	if (false == json.isNull("errmsg")) {
    		result.errmsg = json.getString("errmsg");
    	}
    	if (0 == result.result) {    		
    		result.ext = json.getString("ext");
    		result.callid = json.getString("callid");
    	}    	
    	return result;    	
    }
    

}

6.SmsSingleSender.java

package com.moduyun.sdk.sms.yun;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.util.ArrayList;

// org.json 第三方库请自行下载编译,或者在以下链接下载使用 jdk 1.7 的版本
// http://share.weiyun.com/630a8c65e9fd497f3687b3546d0b839e
import org.json.JSONObject;
 
public class SmsSingleSender {
	String accesskey;
	String secretkey;
	//同时支持http和https两种协议,具体根据自己实际情况使用。
    String url = "https://live.moduyun.com/sms/v1/sendsinglesms";
	SmsSenderUtil util = new SmsSenderUtil();

	public SmsSingleSender(String accesskey, String secretkey) throws Exception {
		this.accesskey = accesskey;
		this.secretkey = secretkey;
	}

	/**
	 * 普通单发短信接口,明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名
	 * @param type 短信类型,0 为普通短信,1 营销短信
	 * @param nationCode 国家码,如 86 为中国
	 * @param phoneNumber 不带国家码的手机号
	 * @param msg 信息内容,必须与申请的模板格式一致,否则将返回错误
	 * @param extend 扩展码,可填空
	 * @param ext 服务端原样返回的参数,可填空
	 * @return {@link}SmsSingleSenderResult
	 * @throws Exception
	 */
	public SmsSingleSenderResult send(
			int type,
			String nationCode,
			String phoneNumber,
			String msg,
			String extend,
			String ext) throws Exception {
/*
请求包体
{
    "tel": {
        "nationcode": "86", 
        "mobile": "13788888888"
    },
    "type": 0, 
    "msg": "你的验证码是1234", 
    "sig": "fdba654e05bc0d15796713a1a1a2318c", 
    "time": 1479888540,
    "extend": "",
    "ext": ""
}
应答包体
{
    "result": 0,
    "errmsg": "OK", 
    "ext": "", 
    "sid": "xxxxxxx", 
    "fee": 1
}
*/
		// 校验 type 类型
		if (0 != type && 1 != type) {
			throw new Exception("type " + type + " error");
		}
		if (null == extend) {
			extend = "";
		}		
		if (null == ext) {
			ext = "";
		}

		// 按照协议组织 post 请求包体
        long random = util.getRandom();
        long curTime = System.currentTimeMillis()/1000;

		JSONObject data = new JSONObject();

        JSONObject tel = new JSONObject();
        tel.put("nationcode", nationCode);
        tel.put("mobile", phoneNumber);

        data.put("type", type);
        data.put("msg", msg);
        data.put("sig", util.strToHash(String.format(
        		"secretkey=%s&random=%d&time=%d&mobile=%s",
        		secretkey, random, curTime, phoneNumber)));
        data.put("tel", tel);
        data.put("time", curTime);
        data.put("extend", extend);
        data.put("ext", ext);

        // 与上面的 random 必须一致
		String wholeUrl = String.format("%s?accesskey=%s&random=%d", url, accesskey, random);
        HttpURLConnection conn = util.getPostHttpConn(wholeUrl);

        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
        wr.write(data.toString());
        wr.flush();
        
        System.out.println(data.toString());

        // 显示 POST 请求返回的内容
        StringBuilder sb = new StringBuilder();
        int httpRspCode = conn.getResponseCode();
        SmsSingleSenderResult result;
        if (httpRspCode == HttpURLConnection.HTTP_OK) {
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
            System.out.println(sb.toString());
            JSONObject json = new JSONObject(sb.toString());
            result = util.jsonToSmsSingleSenderResult(json);
        } else {
        	result = new SmsSingleSenderResult();
        	result.result = httpRspCode;
        	result.errMsg = "http error " + httpRspCode + " " + conn.getResponseMessage();
        }
        
        return result;
	}

	/**
	 * 指定模板单发
	 * @param nationCode 国家码,如 86 为中国
	 * @param phoneNumber 不带国家码的手机号
	 * @param templId 信息内容
	 * @param params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
	 * @param sign 签名,如果填空,系统会使用默认签名
	 * @param extend 扩展码,可填空
	 * @param ext 服务端原样返回的参数,可填空
	 * @return {@link}SmsSingleSenderResult
	 * @throws Exception
	 */
	public SmsSingleSenderResult sendWithParam(
			String nationCode,
			String phoneNumber,
			int templId,
			ArrayList<String> params,
			String sign,
			String extend,
			String ext) throws Exception {
/*
请求包体
{
    "tel": {
        "nationcode": "86", 
        "mobile": "13788888888"
    }, 
    "sign": "Kewail云", 
    "tpl_id": 19, 
    "params": [
        "验证码", 
        "1234", 
        "4"
    ], 
    "sig": "fdba654e05bc0d15796713a1a1a2318c",
    "time": 1479888540,
    "extend": "", 
    "ext": ""
}
应答包体
{
    "result": 0,
    "errmsg": "OK", 
    "ext": "", 
    "sid": "xxxxxxx", 
    "fee": 1
}
*/
		if (null == nationCode || 0 == nationCode.length()) {
			nationCode = "86";
		}
		if (null == params) {
			params = new ArrayList<>();
		}
		if (null == sign) {
			sign = "";
		}
		if (null == extend) {
			extend = "";
		}		
		if (null == ext) {
			ext = "";
		}
		
		long random = util.getRandom();
		long curTime = System.currentTimeMillis()/1000;

		JSONObject data = new JSONObject();

        JSONObject tel = new JSONObject();
        tel.put("nationcode", nationCode);
        tel.put("mobile", phoneNumber);

        data.put("tel", tel);
        data.put("sig", util.calculateSigForTempl(secretkey, random, curTime, phoneNumber));
        data.put("tpl_id", templId);
        data.put("params", util.smsParamsToJSONArray(params));
        data.put("sign", sign);
        data.put("time", curTime);
        data.put("extend", extend);
        data.put("ext", ext);

		String wholeUrl = String.format("%s?accesskey=%d&random=%d", url, accesskey, random);
        HttpURLConnection conn = util.getPostHttpConn(wholeUrl);

        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
        wr.write(data.toString());
        wr.flush();

        // 显示 POST 请求返回的内容
        StringBuilder sb = new StringBuilder();
        int httpRspCode = conn.getResponseCode();
        SmsSingleSenderResult result;
        if (httpRspCode == HttpURLConnection.HTTP_OK) {
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
            JSONObject json = new JSONObject(sb.toString());
            result = util.jsonToSmsSingleSenderResult(json);
        } else {
        	result = new SmsSingleSenderResult();
        	result.result = httpRspCode;
        	result.errMsg = "http error " + httpRspCode + " " + conn.getResponseMessage();
        }
        
        return result;
	}
}

7.SmsSingleSenderResult.java

package com.moduyun.sdk.sms.yun;

public class SmsSingleSenderResult {
/*
{
    "result": 0,
    "errmsg": "OK", 
    "ext": "", 
    "sid": "xxxxxxx", 
    "fee": 1
}
 */
	public int result;
	public String errMsg = "";
	public String ext = "";
	public String sid = "";
	public int fee;
	
	public String toString() {
		return String.format(
				"SmsSingleSenderResult\nresult %d\nerrMsg %s\next %s\nsid %s\nfee %d",
				result, errMsg, ext, sid, fee);		
	}
}

8.SmsStatusPullCallbackResult.java

package com.moduyun.sdk.sms.yun;

import java.util.ArrayList;

public class SmsStatusPullCallbackResult {
	 class Callback{
		String user_receive_time;
		String nationcode;
		String mobile;
		String report_status;
		String errmsg;
		String description;
		String sid;
		public String toString(){
			return String.format("\t"
					+"user_receive_time:%s\t"
					+"nationcode:%s\t"
					+"mobile:%s\t"
					+"errmsg:%s\t"
					+"report_status:%s\t"
					+"description:%s\t"
					+"sid:%s\t",
					user_receive_time, 
					nationcode,
					mobile,
					report_status,
					errmsg,
					description,
					sid
					
		 );
		}
	}
	
	int result;
	String errmsg;
	int count;
	ArrayList<Callback> callbacks;
	
	
	public String toString() {
			return String.format("SmsStatusPullCallbackResult:\n"
					+"result:%d\n"
					+"errmsg:%s\n"
					+"count:%d\n"
					+"callbacks:%s\n",
					result, 
					errmsg,
					count,
					callbacks.toString()
		 );
	}
}

到此完整代码已经结束。最后要做的,就是到:短信服务--->接口短信--->签名管理和内容管理这两个栏目添加签名和提交报备模板即可。

提交短信的时候把内容替换成需要发送的模板如:msg=【签名】+具体内容。

发布了1 篇原创文章 · 获赞 3 · 访问量 3463

猜你喜欢

转载自blog.csdn.net/walking56849/article/details/105286050