【微服务集成阿里SMS短信服务发送短信】

  • 发送短信项目中很多地方都在使用,所以集成一个单独的服务,如果某个服务需要发送短信只需要依赖短信服务即可。

1、开通阿里SMS短信,创建模板 (省略)

2、创建短信服务 common-server-sms

2.1 添加依赖

<dependencies>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <artifactId>common-server-sms</artifactId>

2.2 创建配置文件并添加短信配置

ruyi:
  sms:
    aliyun:
      app-id: xxxxxxxxxxx
      app-secret: xxxxxxx
      sign-name: 自己设置的短信签名
      #模板
      templates: 
         #验证码模板
        VALID_CODE: SMS_234234343(自己设置的)

2.3 创建配置类 读取sms配置

/**
 * @ClassName: AliSmsProperties
 * @Description: 阿里云短信配置类
 * @author: ruyi
 * @date: 2021/12/27 22:45
 */
@Data
@ConfigurationProperties(prefix = "thg.sms.aliyun")
public class AliSmsProperties {

	final static String DEFAULT_PRODUCT="Dysmsapi";

	/**默认域名*/
	final static String DEFAULT_DOMAIN="dysmsapi.aliyuncs.com";
	
	final static String DEFAULT_REGION ="cn-hangzhou";
	
	private String product=DEFAULT_PRODUCT;
	
	private String domain=DEFAULT_DOMAIN;
	
	private String regionId= DEFAULT_REGION;
	
	private String appId;
	
	private String appSecret;
	/**短信签名*/
	private String signName;

	/**
	 * 短信模板集合
	 */
	private Map<String,String> templates=new HashMap<>();
}

2.4 创建发送短信响应类

/**
 * @ClassName: SmsResponse
 * @Description: 短信发送响应
 * @author: ruyi
 * @date: 2021/12/27 22:25
 */
@Data
public class SmsResponse {

    /**
     * 发送是否成功
     */
    private Boolean send;
    /**
     * 错误消息
     */
    private String  msg;

    public SmsResponse(Boolean send, String msg) {
        this.send = send;
        this.msg = msg;
    }

    public SmsResponse(String msg) {
        this.send=Boolean.FALSE;
        this.msg = msg;
    }

    public SmsResponse() {
        this.send=Boolean.TRUE;
    }
}

2.5 创建短信模板类

/**
 * @ClassName: NoticeData
 * @Description: 短信模板
 * @author: ruyi
 * @date: 2021/12/27 22:21
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class NoticeData implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -6624808649341355670L;

	/**
	 * 短信模板类型
	 */
	private String type;
	
	/**
	 * 变量参数
	 */
	private Map<String,String> params;

	
	
}

2.6封装发送手机号和通知消息

/**
 * @ClassName: NoticeInfo
 * @Description: 通知消息
 * @author: wyj
 * @date: 2021/12/27 22:18
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class NoticeInfo implements Serializable{

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
     * 通知内容
     */
    private NoticeData noticeData;

    /**
     * 号码列表
     */
    private Collection<String> phones;
}

2.7 创建短信发送器接口

/**
 * @ClassName: BaseSmsSender
 * @Description: 短信发送器接口
 * @author: ruyi
 * @date: 2021/12/27 22:33
 */
public interface BaseSmsSender {
	/**
	 * 单发
	 * @param data 发送内容
	 * @param mobile 发送手机
	 * @return
	 */
	default SmsResponse send(NoticeData data, String mobile) {
		Assert.notNull(mobile,"mobile must be not null");
		return send(data, Arrays.asList(mobile));
	}

	/**
	 * 群发
	 * @param data 发送内容
	 * @param mobile 发送手机号集合
	 * @return
	 */
	default SmsResponse send(NoticeData data, String... mobile) {
		if(mobile == null) {
			return new SmsResponse("手机号为空");
		}
		return send(data, Arrays.asList(mobile));
	}

	SmsResponse send(NoticeData data,Collection<String> mobiles);

}

2.8 创建短信发送器

/**
 * @ClassName: AliSmsSender
 * @Description: 阿里云短信发送
 * @author: ruyi
 * @date: 2021/12/27 22:45
 */
@Slf4j
public class AliSmsSender implements BaseSmsSender {

    private IAcsClient acsClient;

    private AliSmsProperties smsProperties;

    private static final String OK = "OK";

    public AliSmsSender(AliSmsProperties smsProperties) {
        this.smsProperties = smsProperties;
        initClient();
    }

    private void initClient() {
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        IClientProfile profile = DefaultProfile.getProfile(smsProperties.getRegionId(), smsProperties.getAppId(), smsProperties.getAppSecret());
        DefaultProfile.addEndpoint(smsProperties.getRegionId(), smsProperties.getProduct(), smsProperties.getDomain());
        acsClient = new DefaultAcsClient(profile);
    }

    private SendSmsResponse sendSms(NoticeData data, Collection<String> mobile) {
        SendSmsResponse sendSmsResponse = new SendSmsResponse();
        SendSmsRequest request = buildSmsRequest(data, mobile);
        try {
            sendSmsResponse = acsClient.getAcsResponse(request);
            if (OK.equals(sendSmsResponse.getCode())) {
                log.info("mobile={},data={},result={},send sms success", CollectionUtil.join(mobile, ","),JSONUtil.toJsonStr(data), sendSmsResponse.getMessage());
            }else{
                log.warn("mobile={},data={},result={},send sms failed", CollectionUtil.join(mobile, ","),JSONUtil.toJsonStr(data), sendSmsResponse.getMessage());
            }
        } catch (ClientException e) {
            log.error("send sms failed:mobile={},data:{},result={},exception={}",CollectionUtil.join(mobile, ","),JSONUtil.toJsonStr(data),sendSmsResponse.getMessage(), e.getErrMsg());
            throw new BizException("短信发送失败!");
        }
        return sendSmsResponse;

    }

    private SendSmsRequest buildSmsRequest(NoticeData data, Collection<String> mobile) {
        SendSmsRequest request = new SendSmsRequest();
        request.setSignName(smsProperties.getSignName());
        request.setTemplateCode(smsProperties.getTemplates().get(data.getType()));
        Map<String, String> params = data.getParams();
        if (params != null && params.size() > 0) {
            request.setTemplateParam(JSONUtil.toJsonStr(params));
        }
        request.setPhoneNumbers(CollectionUtil.join(mobile, ","));
        return request;
    }

    @Override
    public SmsResponse send(NoticeData data, Collection<String> mobiles) {
      SendSmsResponse smsResponse=  sendSms(data, mobiles);
      if(OK.equals(smsResponse.getCode())) return new SmsResponse();
      else return new SmsResponse(smsResponse.getMessage());
    }
}

2.9 创建短信配置类

/**
 * @ClassName: AutoAliSmsConfiguration
 * @Description: 阿里云短信配置类
 * @author: ruyi
 * @date: 2021/12/27 22:45
 */
@Configuration
@EnableConfigurationProperties(AliSmsProperties.class)
public class AutoAliSmsConfiguration {

    private final AliSmsProperties smsProperties;

    public AutoAliSmsConfiguration(AliSmsProperties smsProperties) {
        this.smsProperties = smsProperties;
    }

    /**
     * If a candidate bean may be created by another auto-configuration, make sure that the one using this condition runs after.
     * ConditionalOnMissingBean该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean;不存在则创建
     * @return 短信发送器
     */
    @Bean
    @ConditionalOnMissingBean(AliSmsProperties.class)
    public AliSmsSender aliSmsSender() {
        return new AliSmsSender(smsProperties);
    }
}

注意:需要创建spring.factories 自动装配AutoAliSmsConfiguration类
在 resource文件夹创建META-INF文件夹 创建文件spring.factories加入配置

  • spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.ruyi.aliyun.AutoAliSmsConfiguration

配置路径内容如下:
【微服务集成阿里SMS短信服务发送短信】_第1张图片

  • 这里就集成完毕了。

3、使用

3.1 依赖common-server-sms服务

比如我在用户模块需要使用短信服务,那我只在用户服务依赖短信服务common-server-sms

 		<dependency>
            <groupId>cn.wyj</groupId>
            <artifactId>common-server-sms</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

3.2 发送短信

private   final AliSmsSender aliSmsSender;(用的构造注入,也可以直接自己喜欢的注入方式)

 @GetMapping(value = "/send")
 public SmsResponse sendSms() {
        Map<String,String> content = new HashMap<>(16);
        content.put("code", String.valueOf(RandomUtil.randomInt(100000, 999999)));
      return aliSmsSender.send(new NoticeData(SmsConstants.CODE_KEY, content), "153****6968");
    }
  • 注意:NoticeData 对象里面的参数需要一一对应,type是模板类型,params是短信内容

测试 使用postman访问接口 /send

  • 成功

在这里插入图片描述

【微服务集成阿里SMS短信服务发送短信】_第2张图片

你可能感兴趣的:(微服务,java,阿里云)