
# Java
|    样例    | [发送短信示例]、[发送分批短信示例]、[接收状态报告示例]、[接收上行短信示例] |
|---|---|
| **环境要求** | JDK1.8及以上版本。                                                                                                                                                                                                                                             |
   
![](https://support.huaweicloud.com/devg-msgsms/public_sys-resources/notice_3.0-zh-cn.png)
- 发送短信为单模板群发短信示例，发送分批短信为多模板群发短信示例。
- 本文档所述Demo在提供服务的过程中，可能会涉及个人数据的使用，建议您遵从国家的相关法律采取足够的措施，以确保用户的个人数据受到充分的保护。
- 本文档所述Demo仅用于功能演示，不允许客户直接进行商业使用。
- 本文档信息仅供参考，不构成任何要约或承诺。
 
 #### 发送短信示例
本示例代码为[调用API发送短信](https://codelabs.developer.huaweicloud.com/codelabs/samples/96887b14113d4e4b8600eb0e4ca02423)，您还可以使用[发送短信SDK](https://support.huaweicloud.com/sdkreference-msgsms/sms_sdkreference_0008.html)进行短信发送。
需额外引入maven依赖，示例代码中使用了该依赖实现AK/SK签名，发送短信是调用API实现：
![](https://support.huaweicloud.com/devg-msgsms/public_sys-resources/caution_3.0-zh-cn.png)
以下代码示例中的version值，请根据实际的SDK版本号进行替换。具体的SDK版本号请参见[SDK开发中心](https://console.huaweicloud.com/apiexplorer/#/sdkcenter/SMSApi?lang=Java)。
```
<dependency>
    <groupId>com.huaweicloud.sdk</groupId>
    <artifactId>huaweicloud-sdk-smsapi</artifactId>
    <version>3.1.125</version>
</dependency>
```
```
package com.huawei.smsapi;
import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.http.HttpMethod;
import com.huaweicloud.sdk.core.http.HttpRequest;
import com.huaweicloud.sdk.smsapi.utils.SmsAkSkSigner;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Objects;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
 * Example of Invoking the batchSendSms Interface to Send an SMS Message.
 */
public class BatchSendSms {
    private static CloseableHttpClient httpClient = null;
    public static void main(String[] args) throws Exception {
        /*
         * Send an SMS message using a special AK/SK authentication algorithm.
         * When the MSGSMS is used to send SMS messages, the AK is app_key, and the SK is app_secret.
         * There will be security risks if the app_key/app_secret used for authentication is directly written into code.
         * We suggest encrypting the app_key/app_secret in the configuration file or environment variables for storage.
         * In this sample, the app_key/app_secret is stored in environment variables for identity authentication.
         * Before running this sample, set the environment variables CLOUD_SDK_MSGSMS_APPKEY and CLOUD_SDK_MSGSMS_APPSECRET.
         * CLOUD_SDK_MSGSMS_APPKEY indicates the application key (app_key), and CLOUD_SDK_MSGSMS_APPSECRET indicates the application secret (app_secret).
         * You can obtain the value from Application Management on the console or by calling the open API of Application Management.
         */
        String ak = System.getenv("CLOUD_SDK_MSGSMS_APPKEY");
        String sk = System.getenv("CLOUD_SDK_MSGSMS_APPSECRET");
        if (Objects.isNull(ak) || Objects.isNull(sk)) {
            System.out.println("the ak or sk is null. please config the environment CLOUD_SDK_MSGSMS_APPKEY and CLOUD_SDK_MSGSMS_APPSECRET first!");
            return;
        }
        // To prevent API invoking failures caused by HTTPS certificate authentication failures, ignore the certificate trust issue to simplify the sample code.
        httpClient = createIgnoreSSLHttpClient();
        sendSms(ak, sk);
    }
    /**
     * Example of Invoking the batchSendSms Interface to Send an SMS Message
     * @param ak AK is the app_key of the SMS application.
     * @param sk SK is the app_secret of the SMS application.
     * @throws UnsupportedEncodingException
     */
    private static void sendSms(String ak, String sk) throws UnsupportedEncodingException {
        // This address is of Beijing 4. Replace it with the actual value.
        String uri = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1";
        // Construct the message body of the sample code.
        // For details about how to construct a body, see the API description.
        StringBuilder body = new StringBuilder();
        appendToBody(body, "from=", "8824110605***");
        appendToBody(body, "&to=", "+86137****3774");
        appendToBody(body, "&templateId=", "e1440669a4354ccdb56ebf2283c6c***");
        appendToBody(body, "&templateParas=", "[\"1\",\"2\",\"3\"]");
        appendToBody(body, "&statusCallback=", "https://test/report");
        System.out.println("body:" + body);
        // Signature operation of the batchsendsms interface
        Map<String, String> signedHeaders = sign(ak, sk, body.toString(), uri);
        if (Objects.isNull(signedHeaders)) {
            System.out.println("sign failed!");
            return;
        }
        // Print Signature Results
        System.out.println("BatchSendSms sign result:" + signedHeaders);
        HttpPost postRequest = new HttpPost(uri);
        postRequest.setHeader("Accept", "application/json");
        postRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
        signedHeaders.forEach((key, value) -> postRequest.setHeader(key, value));
        postRequest.setEntity(new StringEntity(body.toString(), StandardCharsets.UTF_8));
        // Invoke /sms/batchSendSms/v1 api to send messages
        try (CloseableHttpResponse response = httpClient.execute(postRequest)) {
            // Print the response status code.
            System.out.println("Response Status Code: " + response.getStatusLine().getStatusCode());
            // Print the response content.
            System.out.println("Response Content: " + EntityUtils.toString(response.getEntity()));
        } catch (IOException e) {
            System.out.println("response exception:" + e);
        }
    }
    /**
     * Create an HTTP client that ignores the HTTPS certificate check.
     * @return HTTP client
     * @throws Exception
     */
    private static CloseableHttpClient createIgnoreSSLHttpClient() throws Exception {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,  (x509CertChain, authType) -> true).build();
        return HttpClients.custom().setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)).build();
    }
    /**
     * Add the parameter to the original body after URL encoding.
     * @param body Message body
     * @param key  Parameter key
     * @param val Parameter value
     * @throws UnsupportedEncodingException
     */
    private static void appendToBody(StringBuilder body, String key, String val) throws UnsupportedEncodingException {
        if (null != val && !val.isEmpty()) {
            body.append(key).append(URLEncoder.encode(val, UTF_8.name()));
        }
    }
    /**
     * The algorithm for generating the signature header field (Authorization, X-Sdk-Date, Host) is provided.
     * @param ak AK is the app_key of the SMS application.
     * @param sk SK is the app_secret of the SMS application.
     * @param body Message body to be signed
     * @param endpoint the api uri
     * @return signature header field (Authorization, X-Sdk-Date, Host)
     */
    private static Map<String, String> sign(String ak, String sk, String body, String endpoint) {
        // The signature algorithm uses the AK and SK signature algorithms provided by HUAWEI CLOUD IAM and API Gateway.
        // Signature algorithm implementation. The capabilities provided by the SDK are used here.
        // Developers can also use the signature capability provided by HUAWEI CLOUD APIG. For details, see the following website: https://support.huaweicloud.com/devg-apisign/api-sign-sdk-java.html
        // For the signature operation of an interface, the signature must contain the body.
        return SmsAkSkSigner.sign(HttpRequest.newBuilder().withBodyAsString(body)
                        .withMethod(HttpMethod.POST)
                        .withEndpoint(endpoint)
                        .addHeader("Content-Type", "application/x-www-form-urlencoded").build(),
                new BasicCredentials().withAk(ak).withSk(sk));
    }
}
```
 #### 发送分批短信示例
本示例代码为[调用API发送分批短信](https://codelabs.developer.huaweicloud.com/codelabs/samples/96887b14113d4e4b8600eb0e4ca02423)，您还可以使用[发送短信SDK](https://support.huaweicloud.com/sdkreference-msgsms/sms_sdkreference_0008.html)进行短信发送。
需额外引入maven依赖，示例代码中使用了该依赖实现AK/SK签名，发送短信是调用API实现：
![](https://support.huaweicloud.com/devg-msgsms/public_sys-resources/caution_3.0-zh-cn.png)
以下代码示例中的version值，请根据实际的SDK版本号进行替换。具体的SDK版本号请参见[SDK开发中心](https://console.huaweicloud.com/apiexplorer/#/sdkcenter/SMSApi?lang=Java)。
```
<dependency>
    <groupId>com.huaweicloud.sdk</groupId>
    <artifactId>huaweicloud-sdk-smsapi</artifactId>
    <version>3.1.125</version>
</dependency>
```
```
package com.huawei.smsapi;
import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.http.HttpMethod;
import com.huaweicloud.sdk.core.http.HttpRequest;
import com.huaweicloud.sdk.smsapi.utils.SmsAkSkSigner;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Objects;
/**
 * Example of Invoking the batchSendDiffSms Interface to Send an SMS Message.
 */
public class BatchSendDiffSms {
    private static CloseableHttpClient httpClient = null;
    public static void main(String[] args) throws Exception {
        /*
         * Send an SMS message using a special AK/SK authentication algorithm.
         * When the MSGSMS is used to send SMS messages, the AK is app_key, and the SK is app_secret.
         * There will be security risks if the app_key/app_secret used for authentication is directly written into code.
         * We suggest encrypting the app_key/app_secret in the configuration file or environment variables for storage.
         * In this sample, the app_key/app_secret is stored in environment variables for identity authentication.
         * Before running this sample, set the environment variables CLOUD_SDK_MSGSMS_APPKEY and CLOUD_SDK_MSGSMS_APPSECRET.
         * CLOUD_SDK_MSGSMS_APPKEY indicates the application key (app_key), and CLOUD_SDK_MSGSMS_APPSECRET indicates the application secret (app_secret).
         * You can obtain the value from Application Management on the console or by calling the open API of Application Management.
         */
        String ak = System.getenv("CLOUD_SDK_MSGSMS_APPKEY");
        String sk = System.getenv("CLOUD_SDK_MSGSMS_APPSECRET");
        if (Objects.isNull(ak) || Objects.isNull(sk)) {
            System.out.println("the ak or sk is null. please config the environment CLOUD_SDK_MSGSMS_APPKEY and CLOUD_SDK_MSGSMS_APPSECRET first!");
            return;
        }
        // To prevent API invoking failures caused by HTTPS certificate authentication failures, ignore the certificate trust issue to simplify the sample code.
        httpClient = createIgnoreSSLHttpClient();
        sendSmsUsingDiff(ak, sk);
    }
    /**
     * Example of Invoking the batchSendDiffSms Interface to Send an SMS Message
     * @param ak AK is the app_key of the SMS application.
     * @param sk SK is the app_secret of the SMS application.
     * @throws UnsupportedEncodingException
     */
    private static void sendSmsUsingDiff(String ak, String sk) throws UnsupportedEncodingException {
        // This address is of Beijing 4. Replace it with the actual value.
        String uri = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendDiffSms/v1";
        /*
         * Construct the message body of the sample code.
         * For details about how to construct a body, see the API description.
         * Example is:
           {
              "from": "8824110605***",
              "statusCallback": "https://test/report",
              "smsContent": [{
                  "to": ["+86137****3774", "+86137****3775"],
                  "templateId": "e1440669a4354ccdb56ebf2283c6c***",
                  "templateParas": ["1", "23", "e"]
              },
              {
                  "to": ["+86137****3777"],
                  "templateId": "e1440669a4354ccdb56ebf2283c6c***",
                  "templateParas": ["4", "5", "6"]
              }]
           }
         */
        String body = "{" +
                "    \"from\": \"8824110605***\"," +
                "    \"statusCallback\": \"https://test/report\"," +
                "    \"smsContent\": [{" +
                "        \"to\": [\"+86137****3774\", \"+86137****3775\"]," +
                "        \"templateId\": \"e1440669a4354ccdb56ebf2285666***\"," +
                "        \"templateParas\": [\"1\", \"23\", \"e\"]" +
                "    }," +
                "    {" +
                "        \"to\": [\"+86137****3777\"]," +
                "        \"templateId\": \"e1440669a4354ccdb56ebf2283c6c***\"," +
                "        \"templateParas\": [\"4\", \"5\", \"6\"]" +
                "    }]" +
                "}";
        System.out.println("body:" + body);
        // Signature operation of the batchsenddiffsms interface
        Map<String, String> signedHeaders = sign(ak, sk, body, uri);
        if (Objects.isNull(signedHeaders)) {
            System.out.println("sign failed!");
            return;
        }
        // Print Signature Results
        System.out.println("BatchSendDiffSms sign result:" + signedHeaders);
        // Invoke /sms/batchSendDiffSms/v1 api to send messages
        HttpPost postRequest = new HttpPost(uri);
        postRequest.setHeader("Accept", "application/json");
        postRequest.setHeader("Content-Type", "application/json;charset=utf8");
        signedHeaders.forEach((key, value) -> postRequest.setHeader(key, value));
        postRequest.setEntity(new StringEntity(body.toString(), StandardCharsets.UTF_8));
        try (CloseableHttpResponse response = httpClient.execute(postRequest)) {
            // Print the response status code.
            System.out.println("Response Status Code: " + response.getStatusLine().getStatusCode());
            // Print the response content.
            System.out.println("Response Content: " + EntityUtils.toString(response.getEntity()));
        } catch (IOException e) {
            System.out.println("response exception:" + e);
        }
    }
    /**
     * Create an HTTP client that ignores the HTTPS certificate check.
     * @return HTTP client
     * @throws Exception
     */
    private static CloseableHttpClient createIgnoreSSLHttpClient() throws Exception {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,  (x509CertChain, authType) -> true).build();
        return HttpClients.custom().setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)).build();
    }
    /**
     * The algorithm for generating the signature header field (Authorization, X-Sdk-Date, Host) is provided.
     * @param ak AK is the app_key of the SMS application.
     * @param sk SK is the app_secret of the SMS application.
     * @param body Message body to be signed
     * @param endpoint the api uri
     * @return signature header field (Authorization, X-Sdk-Date, Host)
     */
    private static Map<String, String> sign(String ak, String sk, String body, String endpoint) {
        // The signature algorithm uses the AK and SK signature algorithms provided by HUAWEI CLOUD IAM and API Gateway.
        // Signature algorithm implementation. The capabilities provided by the SDK are used here.
        // Developers can also use the signature capability provided by HUAWEI CLOUD APIG. For details, see the following website: https://support.huaweicloud.com/devg-apisign/api-sign-sdk-java.html
        return SmsAkSkSigner.sign(HttpRequest.newBuilder().withBodyAsString(body)
                        .withMethod(HttpMethod.POST)
                        .withEndpoint(endpoint)
                        .addHeader("Content-Type", "application/json;charset=utf8").build(),
                new BasicCredentials().withAk(ak).withSk(sk));
    }
}
```
 #### 接收状态报告
需要引入的maven依赖为：org.springframework:spring-web:5.3.21（样例版本）
```
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
    /**
     * 同步短信回执
     */
    @PostMapping("/report")
    public void smsHwReport(@RequestParam String smsMsgId,  //发送短信成功时返回的短信唯一标识。
                            @RequestParam(required = false) String total,     //长短信拆分后的短信条数。当短信未拆分时该参数取值为1。
                            @RequestParam(required = false) String sequence,  //长短信拆分后的短信序号，当total参数取值大于1时，该参数才有效。当短信未拆分时该参数取值为1。
                            @RequestParam String status,    //短信状态报告枚举值，常见取值请参考“API参考”
                            @RequestParam(required = false) String source,    //短信状态报告来源：1：短信平台自行产生的状态报告。2：短信中心返回的状态报告。3：华为平台产生的状态报告。
                            @RequestParam(required = false) String updateTime,//短信资源的更新时间，通常为短信平台接收短信状态报告的时间，为UTC时间，格式为：yyyy-MM-dd'T'HH:mm:ss'Z'，该时间会通过urlencode转义为%3a。//当短信平台未收到短信中心上报的状态报告时，会自行构造状态报告，该状态报告中不携带“updateTime”参数。
                            @RequestParam(required = false) String orgCode,   //透传南向网元状态码，仅国际/港澳台短信状态报告携带，国内短信不涉及。//当南向网元未返回状态码时不携带该参数。
                            @RequestParam(required = false) String extend,    //扩展字段，由用户在发送短信的请求中携带。若用户发送短信时未携带extend参数，则状态报告中也不会携带extend参数。
                            @RequestParam(required = false) String to) {      //本条状态报告对应的短信的接收方号码，仅当状态报告中携带了extend参数时才会同时携带该参数。
        System.out.println("  ================receive smsStatusReport ======================");
        System.out.println("smsMsgId: " + smsMsgId);
        System.out.println("total: " + total);
        System.out.println("sequence: " + sequence);
        System.out.println("status: " + status);
        System.out.println("source: " + source);
        System.out.println("updateTime: " + updateTime);
        System.out.println("orgCode: " + orgCode);
        System.out.println("extend: " + extend);
        System.out.println("to: " + to);
    }
}
```
 #### 接收上行短信
需要引入的maven依赖为：org.springframework:spring-web:5.3.21（样例版本）
```
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PostMapping;
@RestController
public class DemoController {
     /*
     * @param smsMsgId   上行短信的唯一标识。
     * @param from       上行短信发送方的号码。
     * @param to         上行短信接收方的号码。
     * @param body       上行短信发送的内容。
     * @param createTime //上行短信创建时间，即短信平台接收到用户发送的上行短信的时间（采用标准UTC格式，例如：2018-02-12T15:30:20Z。不同编程语言中的时间格式转换方式不同，部分语言可参考表 不同编程语言的时间格式）。
     *                   //在控制台创建应用时配置需要“接收上行短信回复时间”后，平台才会在Body中附带此字段，该字段只对http协议的短信生效。
     */
    @PostMapping("/upSMS")
    public void receiveHwSms(@RequestParam String smsMsgId,
                             @RequestParam String from,
                             @RequestParam String to,
                             @RequestParam String body,
                             @RequestParam(required = false) String createTime) {
        System.out.println("  ================receive upSMS ======================");
        // 打印上面的RequestParam
        System.out.println("  smsMsgId: " + smsMsgId);
        System.out.println("  from: " + from);
        System.out.println("  to: " + to);
        System.out.println("  body: " + body);
        System.out.println("  createTime: " + createTime);
    }
}
```
#### 相关推荐
| 相关文档                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 相关产品                                                                                                                                                                  |
|:---|:---|
| - 代码样例：[PHP](https://support.huaweicloud.com/devg-msgsms/sms_04_0013.html)/[Python](https://support.huaweicloud.com/devg-msgsms/sms_04_0014.html)/[C#](https://support.huaweicloud.com/devg-msgsms/sms_04_0015.html)/[3.1.5-Node.js](https://support.huaweicloud.com/devg-msgsms/sms_04_0016.html)/[3.1.6-Go](https://support.huaweicloud.com/devg-msgsms/sms_04_0017.html)  - [发送短信API](https://support.huaweicloud.com/api-msgsms/sms_05_0001.html)  - [发送分批短信API](https://support.huaweicloud.com/api-msgsms/sms_05_0002.html)  - [接收状态报告API](https://support.huaweicloud.com/api-msgsms/sms_05_0003.html)  - [接收上行短信API](https://support.huaweicloud.com/api-msgsms/sms_05_0004.html)  - [调测问题处理](https://support.huaweicloud.com/api-msgsms/sms_05_0050.html)   | [语音通话](https://www.huaweicloud.com/product/voice.html) [隐私保护通话](https://www.huaweicloud.com/product/privatenumber.html) |
   
