智慧云信

JAVA实现国际短信验证码发送接口的完整指南

圆点

本文将详细介绍如何使用JAVA语言快速接入国际短信API接口,实现国际验证码短信的发送功能,拿来就能用,10分钟就能完成接入

你好测试abc


354812298791aasx

主要提供两大功能:你好World2023*

单条短信发送(支持黑名单等拦截错误实时返回)354812298791aasx

获取状态报告(每条短信状态仅可获取一次)

Random你好456


你好World2023*

完整java代码实现World测试789

以下是完整的java示例代码,只需替换配置参数即可使用:

你好测试abc

java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;/**
 * 3yit.com国际短信接口Java Demo
 * 功能:发送国际验证码短信、获取状态报告
 * 版本:1.0
 */public class InternationalSMSDemo {
    
    // ==================== 配置区域 ====================
    private static final String SP_ID = "908452"; // 替换为您的SP_ID
    private static final String RAW_PASSWORD = "your_raw_password"; // 替换为您的原始密码
    private static final String API_SEND_URL = "https://api.3yit.com/api/send-sms-single";
    private static final String API_REPORT_URL = "https://api.3yit.com/api/report";
    // ==================== 配置结束 ====================
    
    private static final String PASSWORD;
    
    static {
        // 自动将密码转换为MD5格式
        PASSWORD = md5(RAW_PASSWORD);
    }
    
    /**
     * 发送单条国际验证码短信
     * @param mobile 国际手机号(格式:国家代码+号码,如639257890123)
     * @param message 短信内容
     * @param ext 扩展号(可选)
     * @return 返回结果
     */
    public static SMSResult sendVerificationCode(String mobile, String message, String ext) {
        try {
            // 准备请求参数
            String params = "sp_id=" + URLEncoder.encode(SP_ID, "UTF-8") +
                    "&mobile=" + URLEncoder.encode(mobile, "UTF-8") +
                    "&content=" + URLEncoder.encode(message, "UTF-8") +
                    "&password=" + URLEncoder.encode(PASSWORD, "UTF-8") +
                    (ext != null && !ext.isEmpty() ? "&ext=" + URLEncoder.encode(ext, "UTF-8") : "");
            
            // 发送POST请求
            String result = httpPost(API_SEND_URL, params);
            
            // 解析返回的JSON
            SMSResult smsResult = parseSendResult(result);
            
            if (smsResult != null) {
                return smsResult;
            } else {
                return new SMSResult(false, "API响应解析失败", result);
            }
        } catch (Exception e) {
            return new SMSResult(false, "发送短信时发生异常: " + e.getMessage(), null);
        }
    }
    
    /**
     * 获取状态报告
     * @return 返回状态报告数据
     */
    public static ReportResult getReport() {
        try {
            // 准备请求参数
            String params = "sp_id=" + URLEncoder.encode(SP_ID, "UTF-8") +
                    "&password=" + URLEncoder.encode(PASSWORD, "UTF-8");
            
            String url = API_REPORT_URL + "?" + params;
            
            // 发送GET请求
            String result = httpGet(url);
            
            // 解析返回的JSON
            return parseReportResult(result);
        } catch (Exception e) {
            return new ReportResult(false, "获取状态报告时发生异常: " + e.getMessage(), null, null);
        }
    }
    
    /**
     * 发送HTTP POST请求
     * @param url 请求地址
     * @param params 请求参数
     * @return 响应内容
     */
    private static String httpPost(String url, String params) {
        HttpURLConnection connection = null;
        try {
            URL apiUrl = new URL(url);
            connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setDoOutput(true);
            connection.setConnectTimeout(30000);
            connection.setReadTimeout(30000);
            
            // 发送请求
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = params.getBytes("utf-8");
                os.write(input, 0, input.length);
            }
            
            // 获取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                StringBuilder response = new StringBuilder();
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(connection.getInputStream(), "utf-8"))) {
                    String responseLine;
                    while ((responseLine = br.readLine()) != null) {
                        response.append(responseLine.trim());
                    }
                }
                return response.toString();
            } else {
                return "{\"code\":" + responseCode + ",\"msg\":\"HTTP错误:" + responseCode + "\"}";
            }
        } catch (Exception e) {
            return "{\"code\":-1,\"msg\":\"请求异常:" + e.getMessage() + "\"}";
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
    
    /**
     * 发送HTTP GET请求
     * @param url 请求地址
     * @return 响应内容
     */
    private static String httpGet(String url) {
        HttpURLConnection connection = null;
        try {
            URL apiUrl = new URL(url);
            connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(30000);
            connection.setReadTimeout(30000);
            
            // 获取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                StringBuilder response = new StringBuilder();
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(connection.getInputStream(), "utf-8"))) {
                    String responseLine;
                    while ((responseLine = br.readLine()) != null) {
                        response.append(responseLine.trim());
                    }
                }
                return response.toString();
            } else {
                return "{\"code\":" + responseCode + ",\"msg\":\"HTTP错误:" + responseCode + "\"}";
            }
        } catch (Exception e) {
            return "{\"code\":-1,\"msg\":\"请求异常:" + e.getMessage() + "\"}";
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
    
    /**
     * 解析发送结果
     * @param json 响应JSON
     * @return 发送结果对象
     */
    private static SMSResult parseSendResult(String json) {
        try {
            // 简单JSON解析,实际项目中可以使用JSON库如Jackson或Gson
            int codeStart = json.indexOf("\"code\":") + 7;
            int codeEnd = json.indexOf(",", codeStart);
            if (codeEnd == -1) codeEnd = json.indexOf("}", codeStart);
            int code = Integer.parseInt(json.substring(codeStart, codeEnd).trim());
            
            int msgStart = json.indexOf("\"msg\":\"") + 7;
            int msgEnd = json.indexOf("\"", msgStart);
            String msg = json.substring(msgStart, msgEnd);
            
            if (code == 0) {
                int msgIdStart = json.indexOf("\"msg_id\":\"") + 10;
                int msgIdEnd = json.indexOf("\"", msgIdStart);
                String msgId = json.substring(msgIdStart, msgIdEnd);
                return new SMSResult(true, msg, msgId, null);
            } else {
                String data = null;
                if (json.contains("\"data\":")) {
                    int dataStart = json.indexOf("\"data\":\"") + 8;
                    int dataEnd = json.indexOf("\"", dataStart);
                    data = json.substring(dataStart, dataEnd);
                }
                return new SMSResult(false, getErrorMessage(code, data), null, data);
            }
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 解析报告结果
     * @param json 响应JSON
     * @return 报告结果对象
     */
    private static ReportResult parseReportResult(String json) {
        try {
            // 简单JSON解析
            int codeStart = json.indexOf("\"code\":") + 7;
            int codeEnd = json.indexOf(",", codeStart);
            if (codeEnd == -1) codeEnd = json.indexOf("}", codeStart);
            int code = Integer.parseInt(json.substring(codeStart, codeEnd).trim());
            
            int msgStart = json.indexOf("\"msg\":\"") + 7;
            int msgEnd = json.indexOf("\"", msgStart);
            String msg = json.substring(msgStart, msgEnd);
            
            if (code == 0) {
                List reports = new ArrayList();
                if (json.contains("\"data\":\"")) {
                    int dataStart = json.indexOf("\"data\":\"") + 8;
                    int dataEnd = json.indexOf("\"", dataStart);
                    String data = json.substring(dataStart, dataEnd);
                    
                    if (!data.isEmpty()) {
                        String[] reportList = data.split("\\|");
                        for (String report : reportList) {
                            String[] fields = report.split(",");
                            if (fields.length >= 5) {
                                reports.add(new Report(
                                    fields[0], 
                                    fields[1], 
                                    fields[2], 
                                    fields[3], 
                                    fields[4],
                                    fields.length > 5 ? fields[5] : ""
                                ));
                            }
                        }
                    }
                }
                return new ReportResult(true, msg, reports, null);
            } else {
                return new ReportResult(false, getErrorMessage(code), null, null);
            }
        } catch (Exception e) {
            return new ReportResult(false, "解析报告结果时发生异常: " + e.getMessage(), null, null);
        }
    }
    
    /**
     * MD5加密
     * @param input 原始字符串
     * @return MD5加密后的字符串
     */
    private static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException("MD5加密失败", e);
        }
    }
    
    /**
     * 获取错误信息
     * @param code 错误码
     * @param data 错误数据
     * @return 错误描述
     */
    private static String getErrorMessage(int code, String data) {
        switch (code) {
            case 10000: return "服务出错,请稍后再试";
            case 10001: return "参数错误,请确认";
            case 10008: return "账号被锁定,请联系管理员确认";
            case 10011: return "余额不足,请尽快充值";
            case 10100: return "签名校验失败";
            case 10101: return "您的ip不在白名单内,请确认";
            case 10102: return "密码错误,请确认";
            case 10200: return "产品sp_id必须填写";
            case 10201: return "手机号必须填写";
            case 10202: return "短信内容必须填写";
            case 10203: return "发送时间格式必须为UNIX时间戳";
            case 10208: 
                String detail = getDataErrorMessage(data);
                return "短信进拦截" + (detail != null ? ": " + detail : "");
            case 10209: return "触发防刷,请调整配置";
            default: return "未知错误 (代码: " + code + ")";
        }
    }
    
    /**
     * 获取错误信息
     * @param code 错误码
     * @return 错误描述
     */
    private static String getErrorMessage(int code) {
        return getErrorMessage(code, null);
    }
    
    /**
     * 获取数据错误信息
     * @param data 错误数据
     * @return 错误描述
     */
    private static String getDataErrorMessage(String data) {
        if (data == null) return null;
        
        switch (data) {
            case "WL:MBLJ": return "短信内容匹配到了模板,并且此模板类型是拦截";
            case "WL:MBSH": return "命中审核模板";
            case "WL:NMLJ": return "短信内容没有匹配到模板,并且用户的模板审核方式是未匹配到就进拦截";
            case "WL:NMSH": return "短信内容没有匹配到模板,并且用户的模板审核方式是未匹配到就进审核";
            case "WL:KHLJ": return "命中空号,进拦截";
            case "WL:QHLJ": return "命中用户签名黑名单,进拦截";
            case "WL:SHLJ": return "命中用户SPID黑名单,进拦截";
            case "WL:CHLJ": return "命中系统产品黑名单,进拦截";
            case "WL:CWHM": return "错误号码";
            case "WL:QWBB": return "签名未报备,进拦截";
            case "WL:MQM": return "需要签名但没有,进拦截";
            case "WL:CS": return "超过限速了";
            case "WL:ZJLJ": return "不匹配任何模板,直接拦截";
            case "WL:CMT": return "产品未配置相应通道,进拦截";
            case "WL:CDQC": return "通道不支持该地区发送,进拦截";
            case "WL:CGMT": return "产品通道池中没有相应通道,进拦截";
            case "WL:CNH": return "所选的通道不健康,进拦截";
            case "WL:TCLJ": return "不在发送时间段,进拦截";
            case "WL:TCSH": return "不在发送时间段,进审核";
            case "WL:CPL": return "超频限制";
            default: return null;
        }
    }
    
    /**
     * 短信发送结果类
     */
    public static class SMSResult {
        private boolean success;
        private String message;
        private String msgId;
        private String data;
        
        public SMSResult(boolean success, String message, String msgId, String data) {
            this.success = success;
            this.message = message;
            this.msgId = msgId;
            this.data = data;
        }
        
        public SMSResult(boolean success, String message, String data) {
            this(success, message, null, data);
        }
        
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public String getMsgId() { return msgId; }
        public String getData() { return data; }
    }
    
    /**
     * 状态报告结果类
     */
    public static class ReportResult {
        private boolean success;
        private String message;
        private List reports;
        private String data;
        
        public ReportResult(boolean success, String message, List reports, String data) {
            this.success = success;
            this.message = message;
            this.reports = reports;
            this.data = data;
        }
        
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public List getReports() { return reports; }
        public String getData() { return data; }
    }
    
    /**
     * 状态报告类
     */
    public static class Report {
        private String ext;
        private String msgId;
        private String mobile;
        private String status;
        private String time;
        private String price;
        
        public Report(String ext, String msgId, String mobile, String status, String time, String price) {
            this.ext = ext;
            this.msgId = msgId;
            this.mobile = mobile;
            this.status = status;
            this.time = time;
            this.price = price;
        }
        
        public String getExt() { return ext; }
        public String getMsgId() { return msgId; }
        public String getMobile() { return mobile; }
        public String getStatus() { return status; }
        public String getTime() { return time; }
        public String getPrice() { return price; }
    }
    
    /**
     * 使用示例
     */
    public static void main(String[] args) {
        // 示例1:发送验证码短信
        String mobile = "639257890123"; // 国际手机号(菲律宾示例)
        int verificationCode = (int) (Math.random() * 9000) + 1000; // 生成随机验证码
        String message = "Your verification code is " + verificationCode + ". Please use it within 10 minutes.";
        
        SMSResult result = sendVerificationCode(mobile, message, "");
        
        if (result.isSuccess()) {
            System.out.println("短信发送成功!消息ID: " + result.getMsgId());
            // 这里应该将msg_id保存到数据库,与用户关联
        } else {
            System.out.println("短信发送失败: " + result.getMessage());
        }
        
        // 示例2:获取状态报告
        // ReportResult reportResult = getReport();
        // if (reportResult.isSuccess()) {
        //     System.out.println("获取到 " + reportResult.getReports().size() + " 条状态报告");
        //     for (Report report : reportResult.getReports()) {
        //         System.out.println("手机号: " + report.getMobile() + 
        //                 ", 状态: " + report.getStatus() + 
        //                 ", 时间: " + report.getTime());
        //     }
        // } else {
        //     System.out.println("获取状态报告失败: " + reportResult.getMessage());
        // }
    }}

使用说明

1. 配置参数

在使用代码前,需要修改以下配置参数:

java
private static final String SP_ID = "908452"; // 替换为您的SP_IDprivate static final String RAW_PASSWORD = "your_raw_password"; // 替换为您的原始密码

2. 发送验证码短信

java
// 准备参数String mobile = "639257890123"; // 国际手机号(国家代码+号码,不需要+号)int verificationCode = (int) (Math.random() * 9000) + 1000; // 生成随机验证码String message = "Your verification code is " + verificationCode + ". Please use it within 10 minutes.";// 发送短信SMSResult result = InternationalSMSDemo.sendVerificationCode(mobile, message, "");// 处理结果if (result.isSuccess()) {
    // 发送成功,保存msg_id到数据库
    String msgId = result.getMsgId();
    System.out.println("短信发送成功!消息ID: " + msgId);} else {
    // 发送失败,输出错误信息
    System.out.println("短信发送失败: " + result.getMessage());}

3. 获取状态报告

java
// 获取状态报告ReportResult reportResult = InternationalSMSDemo.getReport();if (reportResult.isSuccess()) {
    System.out.println("获取到 " + reportResult.getReports().size() + " 条状态报告");
    for (Report report : reportResult.getReports()) {
        System.out.println("手机号: " + report.getMobile() + 
                ", 状态: " + report.getStatus() + 
                ", 时间: " + report.getTime());
        // 这里应该更新数据库中相应短信的状态
    }} else {
    System.out.println("获取状态报告失败: " + reportResult.getMessage());}

注意事项

  1. 国际手机号格式:使用国家代码+手机号的格式,不需要添加"+"前缀(例如菲律宾号码:639267890123)

  2. 密码处理:代码已自动将密码进行MD5处理,只需提供原始密码即可

  3. 状态报告:每条短信的状态报告只能获取一次,获取后需要本地存储

  4. 错误处理:代码已包含完整的错误码解析功能,方便定位问题

  5. JSON解析:为了减少依赖,代码使用了简单的字符串处理来解析JSON。在实际项目中,建议使用Jackson或Gson等JSON库

  6. 异常处理:代码已包含基本的异常处理,但实际项目中可能需要更完善的错误处理机制

常见问题

Q: 返回"密码错误"怎么办?
A: 请确认提供的原始密码是否正确,系统会自动进行MD5加密。

Q: 如何知道短信是否发送成功?
A: 发送接口会返回即时结果,也可以通过获取状态报告接口查询发送状态。

Q: 支持哪些国家和地区?
A: 智慧云信国际短信平台支持全球多个国家和地区的短信发送,具体可咨询平台客服。

结语

本文提供的Java代码示例可以帮助开发者快速接入智慧云信国际短信接口,实现验证码短信的发送功能。代码已经过优化,包含完整的错误处理和状态报告功能,只需替换配置参数即可使用。


下一篇
没有了