华为云短信接入实现示例

1)构建Springboot项目

  1. 添加依赖
bash 复制代码
<dependency>
     <groupId>com.huawei.apigateway</groupId>
     <artifactId>java-sdk-core</artifactId>
     <version>3.2.4</version>
</dependency>
  1. 配置文件
java 复制代码
huaweiyun:
  sms:
    url: https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1
    appKey: V******************0
    appSecret: X*******************v
    sender: 8***********9
  1. 配置类
java 复制代码
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * @author admin
 */
@Component
public class SmsConstant implements InitializingBean {

    @Value("${huaweiyun.sms.url}")
    public String smsUrl;
    @Value("${huaweiyun.sms.appKey}")
    public String appKey;
    @Value("${huaweiyun.sms.appSecret}")
    public String appSecret;
    @Value("${huaweiyun.sms.sender}")
    public String smsSender;

    public static String APP_KEY;
    public static String APP_SECRET;
    public static String SMS_URL;
    public static String SMS_SENDER;

    @Override
    public void afterPropertiesSet(){
        APP_KEY = appKey;
        APP_SECRET = appSecret;
        SMS_URL = smsUrl;
        SMS_SENDER = smsSender;
    }

    /*
     * 为了解决base64加密 密钥太长报错问题
     */
    static {
        try {
            Class<?> clazz = Class.forName("javax.crypto.JceSecurity");
            Field nameField = clazz.getDeclaredField("isRestricted");

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(nameField, nameField.getModifiers() & ~Modifier.FINAL);

            nameField.setAccessible(true);
            nameField.set(null, Boolean.FALSE);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

5)使用枚举类定义短信模板

java 复制代码
@AllArgsConstructor
@Getter
public enum MsgTempEnum {

    SMS_VERIFY(1, "短信认证","SMS_VERIFY"),

    FIRE_PUSH_SMS(2, "短信推送","PUSH_SMS"),
    ;

    private final int id;

    private final String name;

    private final String code;

}

6)短信工具类

java 复制代码
import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONUtil;
import com.cloud.apigateway.sdk.utils.Client;
import com.cloud.apigateway.sdk.utils.Request;
import com.zxzx.firecloud.module.base.model.entity.Message;
import com.zxzx.firecloud.module.base.model.entity.TempSms;
import com.zxzx.firecloud.module.base.service.IMessageService;
import com.zxzx.firecloud.module.base.service.ITempSmsService;
import com.zxzx.firecloud.module.uc.model.entity.User;
import com.zxzx.firecloud.module.uc.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author admin
 */
@Slf4j
@Component
public class SendSms {

    public static final String UTF_8 = "UTF-8";

    @Autowired
    private IMessageService messageService;
    @Autowired
    private ITempSmsService tempSmsService;
    @Autowired
    private IUserService userService;

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, String receiver, String param) {
        return sendSms(msgTempEnum, Collections.singletonList(receiver), Collections.singletonList(param));
    }

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, List<String> receiverList, String param) {
        return sendSms(msgTempEnum, receiverList, Collections.singletonList(param));
    }

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, String receiver, List<String> paramList) {
        return sendSms(msgTempEnum, Collections.singletonList(receiver), paramList);
    }

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, List<String> receiverList, List<String> paramList) {
        try {
            TempSms tempSms = tempSmsService.getTempSmsByBusiness(msgTempEnum.getCode());
            String templateId = tempSms.getTemplateId();
            if (ObjUtil.isEmpty(receiverList) || ObjUtil.isEmpty(templateId)) {
                log.error("receiverList or templateId is null");
                return new ArrayList<>();
            }
            String templateParas = "[\"" + StringUtils.join(paramList, "\",\"") + "\"]";
            String receiver = StringUtils.join(receiverList, ",");
            List<SmsResultDetail> responseList = new ArrayList<>();
            try {
                Request request = new Request();
                String body = buildRequestBody(SmsConstant.SMS_SENDER, receiver, templateId, templateParas);
                request.setKey(SmsConstant.APP_KEY);
                request.setSecret(SmsConstant.APP_SECRET);
                request.setUrl(SmsConstant.SMS_URL);
                request.setMethod("POST");
                request.addHeader("Content-Type", "application/x-www-form-urlencoded");
                request.setBody(body);
                HttpRequestBase signedRequest = Client.sign(request, "SDK-HMAC-SHA256");
                HttpResponse response = HttpClientSingleton.getInstance().execute(signedRequest);
                log.info("Print the status line of the response: {}", response.getStatusLine().toString());
                responseList = getResultDetailList(response.getEntity());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            for (SmsResultDetail resultDetail : responseList) {
                Message message = new Message();
                message.setMessageType("SMS");
                message.setMessageContent(MessageFormat.format(tempSms.getTemplateDesc(), paramList.toArray()));
                message.setTitle(tempSms.getName());
                message.setReceiver(resultDetail.getOriginTo());
                message.setCallMessage(resultDetail.toString());
                message.setBusiness(msgTempEnum.getCode());
                message.setStatus(2);
                if ("000000".equals(resultDetail.getStatus())) {
                    message.setStatus(1);
                }
                messageService.save(message);
            }
            return responseList;
        } catch (Exception e) {
            log.error("短信推送失败:{}", e);
            return new ArrayList<>();
        }
    }

    private static List<SmsResultDetail> getResultDetailList(HttpEntity resEntity) throws IOException {
        if (resEntity == null) {
            return new ArrayList<>();
        }
        String res = EntityUtils.toString(resEntity, "UTF-8");
        log.info("Processing Body with name: {} and value: {}", System.getProperty("line.separator"), res);
        SmsResult bean = JSONUtil.toBean(res, SmsResult.class);
        if (bean == null || !"000000".equals(bean.getCode())) {
            return new ArrayList<>();
        }
        List<SmsResultDetail> successList = new ArrayList<>();
        if (ObjUtil.isNotEmpty(bean.getResult())) {
            successList = bean.getResult();
        }
        return successList;
    }

    static String buildRequestBody(String sender, String receiver, String templateId, String templateParas) throws UnsupportedEncodingException {
        StringBuilder body = new StringBuilder();
        appendToBody(body, "from=", sender);
        appendToBody(body, "&to=", receiver);
        appendToBody(body, "&templateId=", templateId);
        appendToBody(body, "&templateParas=", templateParas);
        return body.toString();
    }

    private static void appendToBody(StringBuilder body, String key, String val) throws UnsupportedEncodingException {
        if (ObjUtil.isNotEmpty(val)) {
            body.append(key).append(URLEncoder.encode(val, UTF_8));
        }
    }
}
相关推荐
甄超锋7 分钟前
Java Maven更换国内源
java·开发语言·spring boot·spring·spring cloud·tomcat·maven
m0_7190841124 分钟前
sharding-jdbc读写分离配置
java
还是鼠鼠1 小时前
tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
java·spring boot·后端·spring·maven
Xiaokai丶2 小时前
Java 8 新特性深度剖析:核心要点与代码实战
java
灵魂猎手2 小时前
3. MyBatis Executor:SQL 执行的核心引擎
java·后端·源码
Galaxy在掘金2 小时前
从业8年,谈谈我认知的后端架构之路-1
java·架构
努力努力再努力wz2 小时前
【c++深入系列】:万字详解模版(下)
java·c++·redis
瓦特what?3 小时前
关于C++的#include的超超超详细讲解
java·开发语言·数据结构·c++·算法·信息可视化·数据挖掘
是乐谷4 小时前
阿里云杭州 AI 产品法务岗位信息分享(2025 年 8 月)
java·人工智能·阿里云·面试·职场和发展·机器人·云计算
Java水解4 小时前
Java中的四种引用类型详解:强引用、软引用、弱引用和虚引用
java·后端