阿里云短信接入实现示例

发布于:2025-05-01 ⋅ 阅读:(43) ⋅ 点赞:(0)

1)构建Springboot项目

2)  添加依赖

<!--阿里云短信-->
<dependency>
	<groupId>com.aliyun</groupId>
	<artifactId>alibabacloud-dysmsapi20170525</artifactId>
	<version>3.0.0</version>
</dependency>

<dependency>
	<groupId>com.aliyun</groupId>
	<artifactId>aliyun-java-sdk-idaas-doraemon</artifactId>
	<version>1.3.2</version>
</dependency>
<dependency>
	<groupId>com.aliyun</groupId>
	<artifactId>aliyun-java-sdk-core</artifactId>
	<optional>true</optional>
	<version>[4.4.9,5.0.0)</version>
</dependency>

3) 配置文件

aliyun:
  sms:
    accessKey: V***********y
    accessSecret: e***********************z
    regionId: cn-******
    endPoint: dysm***.al*****.c**

4)配置类

@Component
@Slf4j
public class AliyunConstant implements InitializingBean {

    @Value("${aliyun.sms.accessKey}")
    public String accessKey;
    @Value("${aliyun.sms.accessSecret}")
    public String accessSecret;
    @Value("${aliyun.sms.regionId}")
    public String regionId;
    @Value("${aliyun.sms.endPoint}")
    public String endPoint;

    public static String ACCESS_KEY;
    public static String ACCESS_SECRET;
    public static String REGION_ID;
    public static String END_POINT;

    @Override
    public void afterPropertiesSet(){
        ACCESS_KEY = accessKey;
        ACCESS_SECRET = accessSecret;
        REGION_ID = regionId;
        END_POINT = endPoint;
    }

    /*
     * 为了解决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 e) {
            log.error(e.getMessage(),e);
        }
    }
}

5) 单例客户端 调用频繁可以使用资源池构建

public class AsyncClientSingleton {

    private static final StaticCredentialProvider PROVIDER = StaticCredentialProvider.create(Credential.builder()
            .accessKeyId(AliyunConstant.ACCESS_KEY)
            .accessKeySecret(AliyunConstant.ACCESS_SECRET)
            .build());
    private static final AsyncClient CLIENT = AsyncClient.builder()
            .credentialsProvider(PROVIDER)
            .region(AliyunConstant.REGION_ID)
            .overrideConfiguration(ClientOverrideConfiguration.create().setEndpointOverride(AliyunConstant.END_POINT))
            .build();

    private AsyncClientSingleton() {}
  
    public static AsyncClient getInstance() {
        return CLIENT;
    }  
}

6)短信类型枚举

@AllArgsConstructor
@Getter
public enum MsgTempEnum {

    COOPERATE_INTENTION(10, "标识码验证成功","COOPERATE_INTENTION"),

    EDUCATION_TRAINING(11, "订阅成功","EDUCATION_TRAINING")

}

7) 短信工具类

@Slf4j
@Component
public class SendMsg {

    @Resource
    private IMessageService messageService;

    private static IMessageService messageServiceInstance;

    @PostConstruct
    public void initInstance() {
        messageServiceInstance = messageService;
    }

    public static SendSmsResponseBody sendSms(MsgTempEnum msgTempEnum, String phoneNumbers, Map<String, String> paramsMap) {
        return sendSms(msgTempEnum, Collections.singletonList(phoneNumbers), paramsMap);
    }

    public static SendSmsResponseBody sendSms(MsgTempEnum msgTempEnum, List<String> numbers, Map<String, String> paramsMap) {
        String code = msgTempEnum.getCode();
        MsgTemp msgTemp = InitBaseData.msgTempMap.get(code);
        String phoneNumbers = StringUtils.join(numbers, ",");
        SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
                .phoneNumbers(phoneNumbers)
                .templateCode(msgTemp.getTemplateCode())
                .templateParam(JSONUtil.toJsonStr(paramsMap))
                .signName(CommonConstant.SIGN_NAME)
                .build();
        try {
            CompletableFuture<SendSmsResponse> response = AsyncClientSingleton.getInstance().sendSms(sendSmsRequest);
            SendSmsResponse sendSmsResponse = response.get();
            if (sendSmsResponse == null) {
                return null;
            }
            SendSmsResponseBody respBody = sendSmsResponse.getBody();
            for (String number : numbers) {
                Message message = new Message();
                message.setMessageType("SMS");
                message.setMessageCategory(code);
                message.setMessageContent(MessageFormat.format(msgTemp.getTemplateDesc(), new ArrayList<>(paramsMap.values()).toArray()));
                message.setTitle(msgTemp.getName());
                message.setReceiver(number);
                if (respBody != null) {
                    message.setCallMessage("SmsResult{" + "bizId='" + respBody.getBizId() + ", code='" + respBody.getCode() +
                            ", message='" + respBody.getMessage() + ", requestId='" + respBody.getRequestId() + '}');
                    message.setStatus("OK".equals(respBody.getCode()) ? 1 : 0);
                }
                messageServiceInstance.save(message);
            }
            return sendSmsResponse.getStatusCode() != 200 ? null : respBody;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

}

8) 调用示例

LinkedHashMap可以保证入参顺序一致,方便后台记录短信发送日志。

public void sendNoticeMsg(String receiver, String name, String tel, MsgTempEnum msgTempEnum){
    Map<String,String> map = new LinkedHashMap<>();
    map.put("name",name);
    map.put("tel",tel);
    sendNoticeMsg(receiver,map,msgTempEnum);
}


网站公告

今日签到

点亮在社区的每一天
去签到