diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java index ebbf50b2..85740aee 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java @@ -55,4 +55,9 @@ public abstract class SupplierConstant { */ public static final String LIANLU = "lianlu"; + /** + * 鼎众 + */ + public static final String DINGZHONG = "dingzhong"; + } diff --git a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java index c8409f50..278bdac8 100644 --- a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java +++ b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java @@ -24,6 +24,7 @@ import org.dromara.sms4j.core.factory.SmsFactory; import org.dromara.sms4j.core.proxy.processor.*; import org.dromara.sms4j.core.proxy.SmsProxyFactory; import org.dromara.sms4j.ctyun.config.CtyunFactory; +import org.dromara.sms4j.dingzhong.config.DingZhongFactory; import org.dromara.sms4j.emay.config.EmayFactory; import org.dromara.sms4j.huawei.config.HuaweiFactory; import org.dromara.sms4j.javase.util.YamlUtils; @@ -39,6 +40,12 @@ import org.dromara.sms4j.unisms.config.UniFactory; import org.dromara.sms4j.yunpian.config.YunPianFactory; import org.dromara.sms4j.zhutong.config.ZhutongFactory; +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -99,6 +106,33 @@ public class SEInitializer { if (CollUtil.isEmpty(configList)) { return; } + try{ + Map> blends = new HashMap<>(); + for (SupplierConfig supplierConfig : configList) { + Map param = new HashMap<>(); + String channel = supplierConfig.getSupplier(); + Class clazz = supplierConfig.getClass(); + BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + Method readMethod = propertyDescriptor.getReadMethod(); + Object item = readMethod.invoke(supplierConfig); + param.put(propertyDescriptor.getName(),item); + } + blends.put(channel,param); + } + //持有初始化配置信息 + EnvirmentHolder.frozenEnvirmet(smsConfig, blends); + + //注册执行器实现 + SmsProxyFactory.addProcessor(new RestrictedProcessor()); + SmsProxyFactory.addProcessor(new BlackListProcessor()); + SmsProxyFactory.addProcessor(new BlackListRecordingProcessor()); + SmsProxyFactory.addProcessor(new SingleBlendRestrictedProcessor()); + SmsProxyFactory.addProcessor(new CoreMethodParamValidateProcessor()); + }catch (Exception e){ + log.error("配置对象转换配置信息失败,但不影响基础功能的使用。【注意】:未加载SMS4J扩展功能模块,拦截器,参数校验可能失效!"); + } for (SupplierConfig supplierConfig : configList) { SmsFactory.createSmsBlend(supplierConfig); } @@ -194,6 +228,7 @@ public class SEInitializer { ProviderFactoryHolder.registerFactory(YunPianFactory.instance()); ProviderFactoryHolder.registerFactory(ZhutongFactory.instance()); ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); + ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) { ProviderFactoryHolder.registerFactory(JdCloudFactory.instance()); } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/config/DingZhongConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/config/DingZhongConfig.java new file mode 100644 index 00000000..59bf9901 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/config/DingZhongConfig.java @@ -0,0 +1,45 @@ +package org.dromara.sms4j.dingzhong.config; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.provider.config.BaseConfig; + +/** + * @author Wind + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class DingZhongConfig extends BaseConfig { + + /** + * 模板变量名称 + */ + private String templateName; + + /** + * 请求地址 + */ + private String requestUrl = "http://demoapi.321sms.com:8201"; + + /** + * 基础接口名称 + */ + private String baseAction = "Sms/SendSms"; + + /** + * 模板接口名称 + */ + private String templateAction = "Sms/SendTemplateSms"; + + /** + * 获取供应商 + * + * @since 3.0.0 + */ + @Override + public String getSupplier() { + return SupplierConstant.DINGZHONG; + } + +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/config/DingZhongFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/config/DingZhongFactory.java new file mode 100644 index 00000000..df2f4216 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/config/DingZhongFactory.java @@ -0,0 +1,48 @@ +package org.dromara.sms4j.dingzhong.config; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.dingzhong.service.DingZhongSmsImpl; +import org.dromara.sms4j.provider.factory.AbstractProviderFactory; + +/** + * DingZhongFactory + *

鼎众对象建造者 + * + * @author :Sh1yu + * 2023/12/26 14:54 + **/ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DingZhongFactory extends AbstractProviderFactory { + + private static final DingZhongFactory INSTANCE = new DingZhongFactory(); + + /** + * 获取建造者实例 + * @return 建造者实例 + */ + public static DingZhongFactory instance() { + return INSTANCE; + } + + /** + * 创建短信实现对象 + * @param dingZhongConfig 短信配置对象 + * @return 短信实现对象 + */ + @Override + public DingZhongSmsImpl createSms(DingZhongConfig dingZhongConfig) { + return new DingZhongSmsImpl(dingZhongConfig); + } + + /** + * 获取供应商 + * @return 供应商 + */ + @Override + public String getSupplier() { + return SupplierConstant.DINGZHONG; + } + +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/service/DingZhongSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/service/DingZhongSmsImpl.java new file mode 100644 index 00000000..14de7742 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/service/DingZhongSmsImpl.java @@ -0,0 +1,91 @@ +package org.dromara.sms4j.dingzhong.service; + +import cn.hutool.json.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.comm.delayedTime.DelayedTime; +import org.dromara.sms4j.comm.utils.SmsUtils; +import org.dromara.sms4j.dingzhong.config.DingZhongConfig; +import org.dromara.sms4j.dingzhong.util.DingZhongHelper; +import org.dromara.sms4j.provider.service.AbstractSmsBlend; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + *

类名: DingZhongSmsImpl + *

说明: 鼎众短信实现 + * + * @author :Sh1yu + * 2023/12/26 17:16 + **/ +@Slf4j +public class DingZhongSmsImpl extends AbstractSmsBlend { + + + /** + * DingZhongSmsImpl + *

构造器,用于构造短信实现模块 + * + * @author :Sh1yu + */ + public DingZhongSmsImpl(DingZhongConfig config, Executor pool, DelayedTime delayedTime) { + super(config, pool, delayedTime); + } + + /** + * DingZhongSmsImpl + *

构造器,用于构造短信实现模块 + */ + public DingZhongSmsImpl(DingZhongConfig config) { + super(config); + } + + @Override + public String getSupplier() { + return SupplierConstant.DINGZHONG; + } + + @Override + public SmsResponse sendMessage(String phone, String message) { + DingZhongHelper helper = new DingZhongHelper(getConfig(), http); + Map paramMap = new LinkedHashMap<>(4); + paramMap.put("cdkey", getConfig().getAccessKeyId()); + paramMap.put("password", getConfig().getAccessKeySecret()); + paramMap.put("mobile", phone); + paramMap.put("msg", message); + return helper.smsResponse(paramMap); + } + + @Override + public SmsResponse sendMessage(String phone, LinkedHashMap messages) { + return sendMessage(phone, getConfig().getTemplateId(), messages); + } + + @Override + public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { + DingZhongHelper helper = new DingZhongHelper(getConfig(), http); + Map paramMap = new LinkedHashMap<>(5); + paramMap.put("cdkey", getConfig().getAccessKeyId()); + paramMap.put("password", getConfig().getAccessKeySecret()); + paramMap.put("mobile", phone); + paramMap.put("templateId", templateId); + JSONObject params = new JSONObject(); + params.putAll(messages); + paramMap.put("msgParam", params.toString()); + return helper.smsResponse(paramMap); + } + + @Override + public SmsResponse massTexting(List phones, String message) { + return sendMessage(SmsUtils.arrayToString(phones), message); + } + + @Override + public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { + return sendMessage(SmsUtils.arrayToString(phones), templateId, messages); + } +} \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/util/DingZhongHelper.java b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/util/DingZhongHelper.java new file mode 100644 index 00000000..83f783c7 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/util/DingZhongHelper.java @@ -0,0 +1,68 @@ +package org.dromara.sms4j.dingzhong.util; + +import cn.hutool.json.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.comm.constant.Constant; +import org.dromara.sms4j.comm.exception.SmsBlendException; +import org.dromara.sms4j.comm.utils.SmsHttpUtils; +import org.dromara.sms4j.comm.utils.SmsUtils; +import org.dromara.sms4j.dingzhong.config.DingZhongConfig; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 鼎众 Helper + * + * @author sh1yu + * @since 2023/12/26 20:57 + */ +@Slf4j +public class DingZhongHelper { + + private final DingZhongConfig config; + private final SmsHttpUtils http; + private int retry = 0; + + public DingZhongHelper(DingZhongConfig config, SmsHttpUtils http) { + this.config = config; + this.http = http; + } + + public SmsResponse smsResponse(Map paramMap) { + String url = String.format("%s/%s", config.getRequestUrl(), SmsUtils.isEmpty(paramMap.get("templateId"))?config.getBaseAction():config.getTemplateAction()); + Map headers = new LinkedHashMap<>(2); + headers.put("Accept", Constant.ACCEPT); + headers.put("Content-Type", Constant.FROM_URLENCODED); + SmsResponse smsResponse = null; + try { + smsResponse = getResponse(http.postFrom(url, headers, paramMap)); + } catch (SmsBlendException e) { + smsResponse = new SmsResponse(); + smsResponse.setSuccess(false); + smsResponse.setData(e.getMessage()); + } + if (smsResponse.isSuccess() || retry == config.getMaxRetries()) { + retry = 0; + return smsResponse; + } + return requestRetry(paramMap); + + } + + private SmsResponse requestRetry(Map paramMap) { + http.safeSleep(config.getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return smsResponse(paramMap); + } + + private SmsResponse getResponse(JSONObject resJson) { + SmsResponse smsResponse = new SmsResponse(); + smsResponse.setSuccess("0".equals(resJson.getStr("resCode"))); + smsResponse.setData(resJson); + smsResponse.setConfigId(this.config.getConfigId()); + return smsResponse; + } +} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java index da47f9af..f564574f 100644 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java @@ -15,6 +15,7 @@ import org.dromara.sms4j.core.factory.SmsFactory; import org.dromara.sms4j.core.proxy.processor.*; import org.dromara.sms4j.core.proxy.SmsProxyFactory; import org.dromara.sms4j.ctyun.config.CtyunFactory; +import org.dromara.sms4j.dingzhong.config.DingZhongFactory; import org.dromara.sms4j.emay.config.EmayFactory; import org.dromara.sms4j.huawei.config.HuaweiFactory; import org.dromara.sms4j.jdcloud.config.JdCloudFactory; @@ -103,6 +104,7 @@ public class SmsBlendsInitializer { ProviderFactoryHolder.registerFactory(YunPianFactory.instance()); ProviderFactoryHolder.registerFactory(ZhutongFactory.instance()); ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); + ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); if(SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) { ProviderFactoryHolder.registerFactory(JdCloudFactory.instance()); } diff --git a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java index 40a64d51..70175646 100644 --- a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java +++ b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java @@ -6,6 +6,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; +import org.dromara.sms4j.api.SmsBlend; import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.utils.SmsUtils; @@ -14,6 +15,7 @@ import org.dromara.sms4j.lianlu.service.LianLuSmsImpl; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.Map; @@ -241,4 +243,39 @@ class Sms4jTest { Assert.isTrue(smsResponse.isSuccess()); } + /** + * 鼎众普通短信 + */ + @Test + public void dingZhongSmsTest() { + if (StrUtil.isBlank(PHONE)) { + return; + } + SmsBlend dz = SmsFactory.getBySupplier(SupplierConstant.DINGZHONG); + + LinkedHashMap messages = new LinkedHashMap<>(); + messages.put("code", SmsUtils.getRandomInt(6)); + + ArrayList phones = new ArrayList<>(); + phones.add(PHONE); + phones.add(PHONE); + + SmsResponse smsResponse = dz.sendMessage(PHONE, "测试短信" + SmsUtils.getRandomInt(6)); + log.info(JSONUtil.toJsonStr(smsResponse)); + Assert.isTrue(smsResponse.isSuccess()); + + SmsResponse smsResponse1 = dz.sendMessage(PHONE, messages); + log.info(JSONUtil.toJsonStr(smsResponse1)); + Assert.isTrue(smsResponse1.isSuccess()); + + SmsResponse smsResponse3 = dz.massTexting(phones, "测试短信" + SmsUtils.getRandomInt(6)); + log.info(JSONUtil.toJsonStr(smsResponse3)); + Assert.isTrue(smsResponse3.isSuccess()); + + SmsResponse smsResponse4 = dz.massTexting(phones, "" ,messages); + log.info(JSONUtil.toJsonStr(smsResponse4)); + Assert.isTrue(smsResponse4.isSuccess()); + + } + } \ No newline at end of file diff --git a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java index bfec9afc..8ae6b2d3 100644 --- a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java +++ b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java @@ -16,6 +16,7 @@ import org.dromara.sms4j.core.factory.SmsFactory; import org.dromara.sms4j.core.proxy.processor.*; import org.dromara.sms4j.core.proxy.SmsProxyFactory; import org.dromara.sms4j.ctyun.config.CtyunFactory; +import org.dromara.sms4j.dingzhong.config.DingZhongFactory; import org.dromara.sms4j.emay.config.EmayFactory; import org.dromara.sms4j.huawei.config.HuaweiFactory; import org.dromara.sms4j.jdcloud.config.JdCloudFactory; @@ -101,6 +102,7 @@ public class SmsBlendsInitializer { ProviderFactoryHolder.registerFactory(YunPianFactory.instance()); ProviderFactoryHolder.registerFactory(ZhutongFactory.instance()); ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); + ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); if(SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) { ProviderFactoryHolder.registerFactory(JdCloudFactory.instance()); }