diff --git a/README.md b/README.md
index 4661e9a8..8d397f34 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-
com.dtflys.forest
diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/AbstractSmsBlend.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/AbstractSmsBlend.java
new file mode 100644
index 00000000..9a32765c
--- /dev/null
+++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/AbstractSmsBlend.java
@@ -0,0 +1,211 @@
+package org.dromara.sms4j.api;
+
+import com.dtflys.forest.config.ForestConfiguration;
+import org.dromara.sms4j.api.callback.CallBack;
+import org.dromara.sms4j.api.entity.SmsResponse;
+import org.dromara.sms4j.comm.annotation.Restricted;
+import org.dromara.sms4j.comm.delayedTime.DelayedTime;
+import org.dromara.sms4j.comm.factory.BeanFactory;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.TimerTask;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+
+public abstract class AbstractSmsBlend implements SmsBlend{
+
+ protected final Executor pool;
+ protected final DelayedTime delayed;
+
+ protected final ForestConfiguration http = BeanFactory.getForestConfiguration();
+ protected AbstractSmsBlend(Executor pool, DelayedTime delayed) {
+ this.pool = pool;
+ this.delayed = delayed;
+ }
+
+ protected AbstractSmsBlend() {
+ this.pool = BeanFactory.getExecutor();
+ this.delayed = BeanFactory.getDelayedTime();
+ }
+
+ /**
+ * 说明:发送固定消息模板短信
+ *
此方法将使用配置文件中预设的短信模板进行短信发送
+ *
该方法指定的模板变量只能存在一个(配置文件中)
+ *
如使用的是腾讯的短信,参数字符串中可以同时存在多个参数,使用 & 分隔例如:您的验证码为{1}在{2}分钟内有效,可以传为 message="xxxx"+"&"+"5"
+ * sendMessage
+ *
+ * @param phone 接收短信的手机号
+ * message 消息内容
+ * @author :Wind
+ */
+
+ public abstract SmsResponse sendMessage(String phone, String message);
+
+ /**
+ *
说明:使用自定义模板发送短信
+ * sendMessage
+ *
+ * @param templateId 模板id
+ * @param messages key为模板变量名称 value为模板变量值
+ * @author :Wind
+ */
+
+ public abstract SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages);
+
+ /**
+ * 说明:群发固定模板短信
+ * massTexting
+ *
+ * @author :Wind
+ */
+
+ public abstract SmsResponse massTexting(List phones, String message);
+
+ /**
+ * 说明:使用自定义模板群发短信
+ * massTexting
+ *
+ * @author :Wind
+ */
+
+ public abstract SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages);
+
+ /**
+ * 说明:异步短信发送,固定消息模板短信
+ * sendMessageAsync
+ *
+ * @param phone 要发送的号码
+ * @param message 发送内容
+ * @param callBack 回调
+ * @author :Wind
+ */
+ @Restricted
+ public final void sendMessageAsync(String phone, String message, CallBack callBack){
+ CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
+ smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
+ }
+
+ /**
+ * 说明:异步发送短信,不关注发送结果
+ * sendMessageAsync
+ *
+ * @param phone 要发送的号码
+ * @param message 发送内容
+ * @author :Wind
+ */
+ @Restricted
+ public final void sendMessageAsync(String phone, String message){
+ pool.execute(() -> {
+ sendMessage(phone, message);
+ });
+ }
+
+ /**
+ *
说明:异步短信发送,使用自定义模板发送短信
+ * sendMessage
+ *
+ * @param templateId 模板id
+ * @param messages key为模板变量名称 value为模板变量值
+ * @param callBack 回调
+ * @author :Wind
+ */
+
+ @Restricted
+ public final void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack){
+ CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone,templateId, messages), pool);
+ smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
+ }
+
+ /**
+ * 说明:异步短信发送,使用自定义模板发送短信,不关注发送结果
+ * sendMessageAsync
+ *
+ * @param templateId 模板id
+ * @param messages key为模板变量名称 value为模板变量值
+ * @author :Wind
+ */
+ @Restricted
+ public final void sendMessageAsync(String phone, String templateId, LinkedHashMap messages){
+ pool.execute(() -> {
+ sendMessage(phone, templateId, messages);
+ });
+ }
+
+ /**
+ * 说明:使用固定模板发送延时短信
+ * delayedMessage
+ *
+ * @param phone 接收短信的手机号
+ * @param message 要发送的短信
+ * @param delayedTime 延迟时间
+ * @author :Wind
+ */
+ @Restricted
+ public final void delayedMessage(String phone, String message, Long delayedTime){
+ this.delayed.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ sendMessage(phone, message);
+ }
+ }, delayedTime);
+ }
+
+ /**
+ *
说明:使用自定义模板发送定时短信 sendMessage
+ * delayedMessage
+ *
+ * @param templateId 模板id
+ * @param messages key为模板变量名称 value为模板变量值
+ * @param phone 要发送的手机号
+ * @param delayedTime 延迟的时间
+ * @author :Wind
+ */
+ @Restricted
+ public final void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime){
+ this.delayed.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ sendMessage(phone, templateId, messages);
+ }
+ }, delayedTime);
+ }
+
+ /**
+ * 说明:群发延迟短信
+ * delayMassTexting
+ *
+ * @param phones 要群体发送的手机号码
+ * @author :Wind
+ */
+ @Restricted
+ public final void delayMassTexting(List phones, String message, Long delayedTime){
+ this.delayed.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ massTexting(phones, message);
+ }
+ }, delayedTime);
+ }
+
+ /**
+ * 说明:使用自定义模板发送群体延迟短信
+ * delayMassTexting
+ *
+ * @param phones 要群体发送的手机号码
+ * @param templateId 模板id
+ * @param messages key为模板变量名称 value为模板变量值
+ * @param delayedTime 延迟的时间
+ * @author :Wind
+ */
+ @Restricted
+ public final void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime){
+ this.delayed.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ massTexting(phones, templateId, messages);
+ }
+ }, delayedTime);
+ }
+}
diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/SmsBlend.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/SmsBlend.java
index 31042825..8ee351cf 100644
--- a/sms4j-api/src/main/java/org/dromara/sms4j/api/SmsBlend.java
+++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/SmsBlend.java
@@ -6,136 +6,35 @@ import org.dromara.sms4j.api.entity.SmsResponse;
import java.util.LinkedHashMap;
import java.util.List;
+/**
+ * SmsBlend
+ * 通用接口,定义国内短信方法
+ * @author :Wind
+ * 2023/5/16 16:03
+ **/
public interface SmsBlend {
- /**
- *
说明:发送固定消息模板短信
- *
此方法将使用配置文件中预设的短信模板进行短信发送
- *
该方法指定的模板变量只能存在一个(配置文件中)
- *
如使用的是腾讯的短信,参数字符串中可以同时存在多个参数,使用 & 分隔例如:您的验证码为{1}在{2}分钟内有效,可以传为 message="xxxx"+"&"+"5"
- * sendMessage
- *
- * @param phone 接收短信的手机号
- * message 消息内容
- * @author :Wind
- */
-
SmsResponse sendMessage(String phone, String message);
- /**
- *
说明:使用自定义模板发送短信
- * sendMessage
- *
- * @param templateId 模板id
- * @param messages key为模板变量名称 value为模板变量值
- * @author :Wind
- */
-
SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages);
- /**
- * 说明:群发固定模板短信
- * massTexting
- *
- * @author :Wind
- */
-
SmsResponse massTexting(List phones, String message);
- /**
- * 说明:使用自定义模板群发短信
- * massTexting
- *
- * @author :Wind
- */
-
SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages);
- /**
- * 说明:异步短信发送,固定消息模板短信
- * sendMessageAsync
- *
- * @param phone 要发送的号码
- * @param message 发送内容
- * @param callBack 回调
- * @author :Wind
- */
-
void sendMessageAsync(String phone, String message, CallBack callBack);
- /**
- *
说明:异步发送短信,不关注发送结果
- * sendMessageAsync
- *
- * @param phone 要发送的号码
- * @param message 发送内容
- * @author :Wind
- */
void sendMessageAsync(String phone, String message);
- /**
- *
说明:异步短信发送,使用自定义模板发送短信
- * sendMessage
- *
- * @param templateId 模板id
- * @param messages key为模板变量名称 value为模板变量值
- * @param callBack 回调
- * @author :Wind
- */
-
void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack);
- /**
- * 说明:异步短信发送,使用自定义模板发送短信,不关注发送结果
- * sendMessageAsync
- *
- * @param templateId 模板id
- * @param messages key为模板变量名称 value为模板变量值
- * @author :Wind
- */
void sendMessageAsync(String phone, String templateId, LinkedHashMap messages);
- /**
- * 说明:使用固定模板发送延时短信
- * delayedMessage
- *
- * @param phone 接收短信的手机号
- * @param message 要发送的短信
- * @param delayedTime 延迟时间
- * @author :Wind
- */
void delayedMessage(String phone, String message, Long delayedTime);
- /**
- *
说明:使用自定义模板发送定时短信 sendMessage
- * delayedMessage
- *
- * @param templateId 模板id
- * @param messages key为模板变量名称 value为模板变量值
- * @param phone 要发送的手机号
- * @param delayedTime 延迟的时间
- * @author :Wind
- */
void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime);
- /**
- * 说明:群发延迟短信
- * delayMassTexting
- *
- * @param phones 要群体发送的手机号码
- * @author :Wind
- */
void delayMassTexting(List phones, String message, Long delayedTime);
- /**
- * 说明:使用自定义模板发送群体延迟短信
- * delayMassTexting
- *
- * @param phones 要群体发送的手机号码
- * @param templateId 模板id
- * @param messages key为模板变量名称 value为模板变量值
- * @param delayedTime 延迟的时间
- * @author :Wind
- */
void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime);
}
diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/smsProxy/RestrictedProcess.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/smsProxy/RestrictedProcess.java
new file mode 100644
index 00000000..748cb90d
--- /dev/null
+++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/smsProxy/RestrictedProcess.java
@@ -0,0 +1,43 @@
+package org.dromara.sms4j.api.smsProxy;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.comm.config.SmsConfig;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.comm.utils.SmsUtil;
+import org.dromara.sms4j.comm.utils.TimeExpiredPoolCache;
+
+@Slf4j
+public class RestrictedProcess {
+ static Long minTimer = 60 * 1000L;
+ static Long accTimer = 24 * 60 * 60 * 1000L;
+ public SmsBlendException process(SmsConfig config, String args) throws Exception{
+ TimeExpiredPoolCache instance = TimeExpiredPoolCache.getInstance();//缓存实例
+ Integer accountMax = config.getAccountMax();//每日最大发送量
+ Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
+ if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
+ Integer i = instance.get(args + "max");
+ if (SmsUtil.isEmpty(i)) {
+ instance.put(args + "max", 1, accTimer);
+ } else if (i > accountMax) {
+ log.info("The phone:" + args + ",number of short messages reached the maximum today");
+ return new SmsBlendException("The phone:" + args + ",number of short messages reached the maximum today");
+ } else {
+ instance.put(args + "max", i + 1, accTimer);
+ }
+ }
+ if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
+ Integer o = instance.get(args);
+ if (SmsUtil.isNotEmpty(o)) {
+ if (o < minuteMax) {
+ instance.put(args, o + 1, minTimer);
+ } else {
+ log.info("The phone:", args + " Text messages are sent too often!");
+ return new SmsBlendException("The phone:", args + " Text messages are sent too often!");
+ }
+ } else {
+ instance.put(args, 1, minTimer);
+ }
+ }
+ return null;
+ }
+}
diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/smsProxy/SmsInvocationHandler.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/smsProxy/SmsInvocationHandler.java
new file mode 100644
index 00000000..88c3be47
--- /dev/null
+++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/smsProxy/SmsInvocationHandler.java
@@ -0,0 +1,48 @@
+package org.dromara.sms4j.api.smsProxy;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.SmsBlend;
+import org.dromara.sms4j.comm.config.SmsConfig;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+@Slf4j
+public class SmsInvocationHandler implements InvocationHandler {
+ private SmsBlend smsBlend;
+ private SmsConfig config;
+ private static RestrictedProcess restrictedProcess = new RestrictedProcess();
+
+ private SmsInvocationHandler(SmsBlend smsBlend, SmsConfig config) {
+ this.smsBlend = smsBlend;
+ this.config = config;
+ }
+
+ public static SmsInvocationHandler newSmsInvocationHandler(SmsBlend smsBlend, SmsConfig config){
+ return new SmsInvocationHandler(smsBlend,config);
+ }
+
+ @Override
+ public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
+ Object result = null;
+ if ("sendMessage".equals(method.getName()) || "massTexting".equals(method.getName())) {
+ //取手机号作为参数
+ String phone = (String) objects[0];
+ SmsBlendException smsBlendException = restrictedProcess.process(config,phone);
+ if (!Objects.isNull(smsBlendException)) {
+ throw smsBlendException;
+ }
+ }
+ result = method.invoke(smsBlend, objects);
+ return result;
+ }
+
+ /**
+ * 设置 restrictedProcess
+ */
+ public static void setRestrictedProcess(RestrictedProcess restrictedProcess) {
+ SmsInvocationHandler.restrictedProcess = restrictedProcess;
+ }
+}
diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/SupplierConfig.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/SupplierConfig.java
new file mode 100644
index 00000000..ad17efff
--- /dev/null
+++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/SupplierConfig.java
@@ -0,0 +1,10 @@
+package org.dromara.sms4j.api.universal;
+
+/**
+ * SupplierConfig
+ * 空接口,无含义,只为标定配置类的额外类型
+ * @author :Wind
+ * 2023/5/16 15:14
+ **/
+public interface SupplierConfig {
+}
diff --git a/sms4j-api/src/main/resources/application.properties b/sms4j-api/src/main/resources/application.properties
deleted file mode 100644
index 8b137891..00000000
--- a/sms4j-api/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/aop/AopAdvice.java b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/aop/AopAdvice.java
deleted file mode 100644
index 19ebdd54..00000000
--- a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/aop/AopAdvice.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package org.dromara.sms4j.autoimmit.aop;
-
-
-import org.dromara.sms4j.comm.exception.SmsBlendException;
-import org.dromara.sms4j.comm.config.SmsConfig;
-import org.dromara.sms4j.autoimmit.utils.RedisUtils;
-import org.dromara.sms4j.comm.utils.SmsUtil;
-import org.dromara.sms4j.comm.utils.TimeExpiredPoolCache;
-import org.dromara.sms4j.autoimmit.utils.SpringUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.util.ArrayList;
-
-@Aspect
-@Slf4j
-public class AopAdvice {
-
- private static final Long minTimer = 60 * 1000L;
- private static final Long accTimer = 24 * 60 * 60 * 1000L;
-
- private static final String REDIS_KEY = "sms:restricted:";
-
- @Autowired
- private SmsConfig config;
-
- @Autowired
- private SpringUtil springUtil;
-
-
- @Pointcut("@annotation(org.dromara.sms4j.comm.annotation.Restricted)")
- public void restricted() {
- }
-
- @Around("restricted()")
- public Object restrictedSendMessage(ProceedingJoinPoint p) throws Throwable {
-
- String args = "";
- ArrayList argsList = new ArrayList<>();
- try {
- args = (String) p.getArgs()[0];
- } catch (Exception e) {
- for (Object o : (ArrayList>) p.getArgs()[0]) {
- argsList.add((String) o);
- }
- }
- SmsBlendException process = redisProcess(args);
- if (process != null) {
- throw process;
- }
- argsList.forEach(f -> {
- SmsBlendException proce = null;
- try {
- proce = redisProcess(f);
- } catch (Exception e) {
- log.error(e.getMessage());
- throw new RuntimeException(e);
- }
- if (proce != null) {
- throw proce;
- }
- });
- return p.proceed();
- }
-
- private SmsBlendException process(String args) throws Exception {
- TimeExpiredPoolCache instance = TimeExpiredPoolCache.getInstance();//缓存实例
- Integer accountMax = config.getAccountMax();//每日最大发送量
- Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
- if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
- Integer i = instance.get(args + "max");
- if (SmsUtil.isEmpty(i)) {
- instance.put(args + "max", 1, accTimer);
- } else if (i > accountMax) {
- log.info("The phone:"+args +",number of short messages reached the maximum today");
- return new SmsBlendException("The phone:"+args +",number of short messages reached the maximum today");
- } else {
- instance.put(args + "max", i + 1, accTimer);
- }
- }
- if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
- Integer o = instance.get(args);
- if (SmsUtil.isNotEmpty(o)) {
- if (o < minuteMax) {
- instance.put(args, o + 1, minTimer);
- } else {
- log.info("The phone:"+args +",number of short messages reached the maximum today");
- return new SmsBlendException("The phone:", args + " Text messages are sent too often!");
- }
- } else {
- instance.put(args, 1, minTimer);
- }
- }
- return null;
- }
-
- private SmsBlendException redisProcess(String args) throws Exception{
- if (config.getRedisCache().equals("false")){
- return process(args);
- }
- RedisUtils redis = SpringUtil.getBean(RedisUtils.class);
-
- Integer accountMax = config.getAccountMax();//每日最大发送量
- Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
- if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
- Integer i = (Integer) redis.getByKey(REDIS_KEY+args + "max");
- if (SmsUtil.isEmpty(i)) {
- redis.setOrTime(REDIS_KEY+args + "max", 1,accTimer/1000);
- } else if (i > accountMax) {
- log.info("The phone:"+args +",number of short messages reached the maximum today");
- return new SmsBlendException("The phone:"+args +",number of short messages reached the maximum today");
- } else {
- redis.setOrTime(REDIS_KEY+args + "max", i + 1,accTimer/1000);
- }
- }
- if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
- Integer o = (Integer) redis.getByKey(REDIS_KEY+args);
- if (SmsUtil.isNotEmpty(o)) {
- if (o < minuteMax) {
- redis.setOrTime(REDIS_KEY+args, o + 1,minTimer/1000);
- } else {
- log.info("The phone:"+args +",number of short messages reached the maximum today");
- return new SmsBlendException("The phone:", args + " Text messages are sent too often!");
- }
- } else {
- redis.setOrTime(REDIS_KEY+args, 1,minTimer/1000);
- }
- }
- return null;
- }
-
-}
diff --git a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/aop/RestrictedProcessImpl.java b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/aop/RestrictedProcessImpl.java
new file mode 100644
index 00000000..5710de66
--- /dev/null
+++ b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/aop/RestrictedProcessImpl.java
@@ -0,0 +1,54 @@
+package org.dromara.sms4j.autoimmit.aop;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.smsProxy.RestrictedProcess;
+import org.dromara.sms4j.autoimmit.utils.RedisUtils;
+import org.dromara.sms4j.autoimmit.utils.SpringUtil;
+import org.dromara.sms4j.comm.config.SmsConfig;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.comm.utils.SmsUtil;
+
+import java.util.Objects;
+
+@Slf4j
+public class RestrictedProcessImpl extends RestrictedProcess {
+ private static final Long minTimer = 60 * 1000L;
+ private static final Long accTimer = 24 * 60 * 60 * 1000L;
+ private static final String REDIS_KEY = "sms:restricted:";
+
+
+ @Override
+ public SmsBlendException process(SmsConfig config,String args) throws Exception {
+ RedisUtils redis = SpringUtil.getBean(RedisUtils.class);
+ if (Objects.isNull(redis)){
+ throw new SmsBlendException("The redis tool could not be found");
+ }
+ Integer accountMax = config.getAccountMax();//每日最大发送量
+ Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
+ if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
+ Integer i = (Integer) redis.getByKey(REDIS_KEY + args + "max");
+ if (SmsUtil.isEmpty(i)) {
+ redis.setOrTime(REDIS_KEY + args + "max", 1, accTimer / 1000);
+ } else if (i > accountMax) {
+ log.info("The phone:" + args + ",number of short messages reached the maximum today");
+ return new SmsBlendException("The phone:" + args + ",number of short messages reached the maximum today");
+ } else {
+ redis.setOrTime(REDIS_KEY + args + "max", i + 1, accTimer / 1000);
+ }
+ }
+ if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
+ Integer o = (Integer) redis.getByKey(REDIS_KEY + args);
+ if (SmsUtil.isNotEmpty(o)) {
+ if (o < minuteMax) {
+ redis.setOrTime(REDIS_KEY + args, o + 1, minTimer / 1000);
+ } else {
+ log.info("The phone:" + args + ",number of short messages reached the maximum today");
+ return new SmsBlendException("The phone:", args + " Text messages are sent too often!");
+ }
+ } else {
+ redis.setOrTime(REDIS_KEY + args, 1, minTimer / 1000);
+ }
+ }
+ return null;
+ }
+}
diff --git a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SmsAutowiredConfig.java b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SmsAutowiredConfig.java
index 970b1701..7625abff 100644
--- a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SmsAutowiredConfig.java
+++ b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SmsAutowiredConfig.java
@@ -1,17 +1,17 @@
package org.dromara.sms4j.autoimmit.config;
-import org.dromara.sms4j.autoimmit.aop.AopAdvice;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.smsProxy.SmsInvocationHandler;
+import org.dromara.sms4j.autoimmit.aop.RestrictedProcessImpl;
import org.dromara.sms4j.autoimmit.utils.ConfigUtil;
import org.dromara.sms4j.autoimmit.utils.RedisUtils;
import org.dromara.sms4j.autoimmit.utils.SpringUtil;
import org.dromara.sms4j.comm.config.SmsBanner;
import org.dromara.sms4j.comm.config.SmsConfig;
import org.dromara.sms4j.comm.config.SmsSqlConfig;
+import org.dromara.sms4j.comm.constant.Constant;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
-import org.dromara.sms4j.comm.enumerate.ConfigType;
-import org.dromara.sms4j.comm.enumerate.SupplierType;
import org.dromara.sms4j.comm.factory.BeanFactory;
-import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.core.SupplierSqlConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -71,21 +71,21 @@ public class SmsAutowiredConfig {
return new SupplierSqlConfig();
}
-
void init(){
/* 如果配置中启用了redis,则注入redis工具*/
if (BeanFactory.getSmsConfig().getRedisCache()){
springUtil.createBean(RedisUtils.class);
- log.debug("The redis cache is enabled for sms-aggregation");
+ SmsInvocationHandler.setRestrictedProcess(new RestrictedProcessImpl());
+ log.debug("The redis cache is enabled for sms4j");
}
/* 如果启用了短信限制,则注入AOP组件*/
- if (BeanFactory.getSmsConfig().getRestricted()){
- springUtil.createBean(AopAdvice.class);
- log.debug("SMS restriction is enabled");
- }
+// if (BeanFactory.getSmsConfig().getRestricted()){
+// springUtil.createBean(AopAdvice.class);
+// log.debug("SMS restriction is enabled");
+// }
//打印banner
if (BeanFactory.getSmsConfig().getIsPrint()){
- SmsBanner.PrintBanner("V 2.0.1");
+ SmsBanner.PrintBanner(Constant.VERSION);
}
}
}
diff --git a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SupplierConfig.java b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SupplierConfig.java
index ad90c132..0ae91749 100644
--- a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SupplierConfig.java
+++ b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/config/SupplierConfig.java
@@ -1,9 +1,10 @@
package org.dromara.sms4j.autoimmit.config;
-import org.dromara.sms4j.emay.config.EmayConfig;
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
import org.dromara.sms4j.cloopen.config.CloopenConfig;
import org.dromara.sms4j.core.config.SupplierFactory;
+import org.dromara.sms4j.ctyun.config.CtyunConfig;
+import org.dromara.sms4j.emay.config.EmayConfig;
import org.dromara.sms4j.huawei.config.HuaweiConfig;
import org.dromara.sms4j.jdcloud.config.JdCloudConfig;
import org.dromara.sms4j.tencent.config.TencentConfig;
@@ -72,4 +73,13 @@ public class SupplierConfig {
protected EmayConfig emayConfig(){
return SupplierFactory.getEmayConfig();
}
+
+ /**
+ * 天翼云短信差异化配置
+ */
+ @Bean
+ @ConfigurationProperties(prefix = "sms.ctyun")
+ protected CtyunConfig ctyunConfig(){
+ return SupplierFactory.getCtyunConfig();
+ }
}
diff --git a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/utils/RedisUtils.java b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/utils/RedisUtils.java
index 0331e52f..aa8e1a26 100644
--- a/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/utils/RedisUtils.java
+++ b/sms4j-autoimmit/src/main/java/org/dromara/sms4j/autoimmit/utils/RedisUtils.java
@@ -8,7 +8,11 @@ import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
diff --git a/sms4j-autoimmit/src/main/resources/application.properties b/sms4j-autoimmit/src/main/resources/application.properties
deleted file mode 100644
index 8b137891..00000000
--- a/sms4j-autoimmit/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/sms4j-comm/pom.xml b/sms4j-comm/pom.xml
index 56074827..eff30c00 100644
--- a/sms4j-comm/pom.xml
+++ b/sms4j-comm/pom.xml
@@ -15,11 +15,6 @@
sms4j-comm
-
- com.alibaba
- fastjson
-
-
com.dtflys.forest
forest-core
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/config/SmsConfig.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/config/SmsConfig.java
index 5db5bc13..a7a7c276 100644
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/config/SmsConfig.java
+++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/config/SmsConfig.java
@@ -1,8 +1,8 @@
package org.dromara.sms4j.comm.config;
-import org.dromara.sms4j.comm.enumerate.ConfigType;
import lombok.Data;
+import org.dromara.sms4j.comm.enumerate.ConfigType;
@Data
public class SmsConfig {
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java
index 273853d9..96aed3e1 100644
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java
+++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java
@@ -1,9 +1,6 @@
package org.dromara.sms4j.comm.constant;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
/**
* Constant
* 短信应用常量
@@ -12,6 +9,8 @@ import java.nio.charset.StandardCharsets;
* 2023/3/31 19:33
**/
public abstract class Constant {
+ /** 项目版本号*/
+ public static final String VERSION = "V 2.1.0";
/**
* 用于格式化鉴权头域,给"Authorization"参数赋值
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/delayedTime/DelayedTime.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/delayedTime/DelayedTime.java
index 621b3cfd..bf53f152 100644
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/delayedTime/DelayedTime.java
+++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/delayedTime/DelayedTime.java
@@ -1,6 +1,7 @@
package org.dromara.sms4j.comm.delayedTime;
-import java.util.*;
+import java.util.Timer;
+import java.util.TimerTask;
/**
*
类名: DelayedTime
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/enumerate/SupplierType.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/enumerate/SupplierType.java
deleted file mode 100644
index d096515d..00000000
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/enumerate/SupplierType.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.dromara.sms4j.comm.enumerate;
-
-/**
- * SupplierType
- *
短信供应商枚举
- * @author :Wind
- * 2023/4/7 20:55
- **/
-public enum SupplierType {
- /** 阿里云*/
- ALIBABA("阿里云短信"),
- /** 华为云*/
- HUAWEI("华为云短信"),
- /** 云片*/
- YUNPIAN("云片短信"),
- /** 腾讯云*/
- TENCENT("腾讯云短信"),
- /** 合一短信*/
- UNI_SMS("合一短信"),
- /** 京东云 */
- JD_CLOUD("京东云短信"),
- /** 容联云 */
- CLOOPEN("容联云短信"),
-
- /**
- * 亿美软通
- */
- EMAY("亿美软通"),
- ;
-
-
- private final String name;
-
- SupplierType(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-}
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/JDBCTool.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/JDBCTool.java
index c2cf9980..5c8c1683 100644
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/JDBCTool.java
+++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/JDBCTool.java
@@ -5,7 +5,11 @@ import org.dromara.sms4j.comm.config.SmsSqlConfig;
import org.dromara.sms4j.comm.exception.SmsSqlException;
import org.dromara.sms4j.comm.factory.BeanFactory;
-import java.sql.*;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Map;
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtil.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtil.java
index 3a43859e..d91b6da9 100644
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtil.java
+++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtil.java
@@ -1,45 +1,37 @@
package org.dromara.sms4j.comm.utils;
import cn.hutool.core.bean.BeanUtil;
-import com.alibaba.fastjson.JSONException;
-import com.alibaba.fastjson.JSONObject;
-import org.dromara.sms4j.comm.exception.SmsSqlException;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONUtil;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Random;
+/**
+ * @author wind
+ */
public class SmsUtil {
private SmsUtil() {
} //私有构造防止实例化
-
/**
*
说明:生成一个指定长度的随机字符串,包含大小写英文字母和数字但不包含符号
*
* @param len 要生成的字符串的长度
- * getRandomString
+ * getRandomString
* @author :Wind
*/
public static String getRandomString(int len) {
- String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- StringBuilder sb = new StringBuilder();
- try {
- Random random = SecureRandom.getInstanceStrong();
- for (int i = 0; i < len; i++) {
- int number = random.nextInt(62);
- sb.append(str.charAt(number));
- }
- } catch (NoSuchAlgorithmException e){
- throw new RuntimeException(e);
- }
- return sb.toString();
+ return RandomUtil.randomString(RandomUtil.BASE_CHAR_NUMBER + RandomUtil.BASE_CHAR.toUpperCase(), len);
}
/**
*
说明:获取一个长度为6的随机字符串
- *getRandomString
+ * getRandomString
+ *
* @author :Wind
*/
public static String getRandomString() {
@@ -48,37 +40,29 @@ public class SmsUtil {
/**
*
说明:生成一个指定长度的只有数字组成的随机字符串
+ *
* @param len 要生成的长度
- * getRandomInt
+ * getRandomInt
* @author :Wind
*/
public static String getRandomInt(int len) {
- String str = "0123456789";
- StringBuilder sb = new StringBuilder();
- try {
- Random random = SecureRandom.getInstanceStrong();
- for (int i = 0; i < len; i++) {
- int number = random.nextInt(10);
- sb.append(str.charAt(number));
- }
- } catch (NoSuchAlgorithmException e){
- throw new RuntimeException(e);
- }
- return sb.toString();
+ return RandomUtil.randomString(RandomUtil.BASE_NUMBER, len);
}
/**
* 指定元素是否为null或者空字符串
+ *
* @param str 指定元素
* @return 是否为null或者空字符串
* @author :Wind
*/
public static boolean isEmpty(Object str) {
- return str == null || "".equals(str);
+ return ObjectUtil.isEmpty(str);
}
/**
* 指定元素是否不为 (null或者空字符串)
+ *
* @param str 指定元素
* @return 是否为null或者空字符串
* @author :Wind
@@ -87,43 +71,72 @@ public class SmsUtil {
return !isEmpty(str);
}
- public static String listToString(List list) {
- StringBuilder str = new StringBuilder();
- for (int i = 0; i < list.size(); i++) {
- if (i == list.size() - 1) {
- str.append(list.get(i));
- } else {
- str.append(list.get(i));
- str.append(",");
- }
- }
- return str.toString();
- }
-
/**
- * jsonForObject
+ * jsonForObject
* 将json字符串转化为指定的对象
+ *
* @author :Wind
- */
+ */
public static T jsonForObject(String json, Class t) {
- try {
- return json == null||"".equals(json)?null: JSONObject.toJavaObject(JSONObject.parseObject(json), t);
- } catch (JSONException e) {
- throw new SmsSqlException("json sequence exception" + e.getMessage());
- }
+ return JSONUtil.toBean(json, t);
}
/**
- * copyBean
+ * copyBean
* 拷贝bean,只有源对象不为null才会拷贝
+ *
* @param t 源对象
* @param m 目标对象
* @author :Wind
- */
- public static void copyBean(T t,M m){
- if (t != null){
- BeanUtil.copyProperties(t, m);
- }
+ */
+ public static void copyBean(T t, M m) {
+ BeanUtil.copyProperties(t, m);
}
-}
+ /**
+ * getNewMap
+ * 获取一个新的空LinkedHashMap
+ *
+ * @return 空的 LinkedHashMap 实例
+ * @author :Wind
+ */
+ public static LinkedHashMap getNewMap() {
+ return new LinkedHashMap<>();
+ }
+
+ /**
+ * listToString
+ * 将list转化为string,元素之间使用逗号分隔,此方法只支持list内部元素为String类型的
+ *
+ * @param list 要转换的list
+ * @author :Wind
+ */
+ public static String listToString(List list) {
+ return CollUtil.join(list, ",");
+ }
+
+ /**
+ * 以 conjunction 为分隔符将集合转换为字符串
+ *
+ * @param list 集合
+ * @return 结果字符串
+ */
+ public static String arrayToString(List list) {
+ return CollUtil.join(list, ",", "+86", "");
+ }
+
+ /**
+ * List +86后转 数组
+ *
+ * @param list 集合
+ * @return 结果字符串
+ */
+ public static String[] listToArray(List list) {
+ List toStr = new ArrayList<>();
+ for (String s : list) {
+ toStr.add("+86" + s);
+ }
+ return toStr.toArray(new String[list.size()]);
+ }
+
+}
\ No newline at end of file
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/TimeExpiredPoolCache.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/TimeExpiredPoolCache.java
index 0eccf02c..1ffaf16d 100644
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/TimeExpiredPoolCache.java
+++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/TimeExpiredPoolCache.java
@@ -1,9 +1,9 @@
package org.dromara.sms4j.comm.utils;
-import com.alibaba.fastjson.JSONObject;
-import org.dromara.sms4j.comm.exception.SmsBlendException;
+import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
import java.io.File;
import java.io.IOException;
@@ -66,8 +66,7 @@ public class TimeExpiredPoolCache {
private static boolean persistenceInit() {
String path = FileTool.getPath() + FILE_TYPE;
try {
-
- DataWrapper d = JSONObject.parseObject(FileTool.readFile(path), DataWrapper.class);
+ DataWrapper d = JSONUtil.toBean(FileTool.readFile(path), DataWrapper.class);
if (dataPool != null) {
return true;
}
@@ -95,7 +94,7 @@ public class TimeExpiredPoolCache {
private static void persistence() {
String path = FileTool.getPath() + FILE_TYPE;
FileTool.createFile(path);
- FileTool.writeFile(new File(path), JSONObject.toJSONString(dataPool), false);
+ FileTool.writeFile(new File(path), JSONUtil.toJsonStr(dataPool), false);
}
/**
diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/http/HttpJsonTool.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/http/HttpJsonTool.java
deleted file mode 100644
index c3137437..00000000
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/http/HttpJsonTool.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.dromara.sms4j.comm.utils.http;
-
-import com.alibaba.fastjson.JSONObject;
-
-import java.io.IOException;
-
-public class HttpJsonTool {
-
-
- public static T getJSONBody(Object response,Classt){
- return JSONObject.parseObject(response.toString(), t);
- }
-
- public static T getJSONBody(String response,Classt){
- return JSONObject.parseObject(response, t);
- }
-
- public static JSONObject getJSONObject(Object obj){
- return JSONObject.parseObject(obj.toString());
- }
-}
diff --git a/sms4j-comm/src/main/resources/application.properties b/sms4j-comm/src/main/resources/application.properties
deleted file mode 100644
index 8b137891..00000000
--- a/sms4j-comm/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/sms4j-core/src/main/java/org/dromara/sms4j/core/SupplierSqlConfig.java b/sms4j-core/src/main/java/org/dromara/sms4j/core/SupplierSqlConfig.java
index ab37636b..48c9bf92 100644
--- a/sms4j-core/src/main/java/org/dromara/sms4j/core/SupplierSqlConfig.java
+++ b/sms4j-core/src/main/java/org/dromara/sms4j/core/SupplierSqlConfig.java
@@ -2,13 +2,14 @@ package org.dromara.sms4j.core;
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
import org.dromara.sms4j.cloopen.config.CloopenConfig;
-import org.dromara.sms4j.comm.enumerate.SupplierType;
import org.dromara.sms4j.comm.utils.JDBCTool;
import org.dromara.sms4j.comm.utils.SmsUtil;
import org.dromara.sms4j.core.config.SupplierFactory;
+import org.dromara.sms4j.ctyun.config.CtyunConfig;
import org.dromara.sms4j.emay.config.EmayConfig;
import org.dromara.sms4j.huawei.config.HuaweiConfig;
import org.dromara.sms4j.jdcloud.config.JdCloudConfig;
+import org.dromara.sms4j.provider.enumerate.SupplierType;
import org.dromara.sms4j.tencent.config.TencentConfig;
import org.dromara.sms4j.unisms.config.UniConfig;
import org.dromara.sms4j.yunpian.config.YunpianConfig;
@@ -48,6 +49,7 @@ public class SupplierSqlConfig {
yunPian();
cloopen();
emay();
+ ctyun();
}
public SupplierSqlConfig() {
@@ -136,4 +138,14 @@ public class SupplierSqlConfig {
EmayConfig emayConfig = SmsUtil.jsonForObject(select.get(SupplierType.EMAY.getName()), EmayConfig.class);
SupplierFactory.setEmayConfig(emayConfig);
}
+
+ /**
+ * ctyun
+ * 数据库读取并设置天翼云短信
+ * @author :Wind
+ */
+ public static void ctyun(){
+ CtyunConfig ctyunConfig = SmsUtil.jsonForObject(select.get(SupplierType.CTYUN.getName()), CtyunConfig.class);
+ SupplierFactory.setCtyunConfig(ctyunConfig);
+ }
}
diff --git a/sms4j-core/src/main/java/org/dromara/sms4j/core/config/SupplierFactory.java b/sms4j-core/src/main/java/org/dromara/sms4j/core/config/SupplierFactory.java
index d494d9a7..d9765bf2 100644
--- a/sms4j-core/src/main/java/org/dromara/sms4j/core/config/SupplierFactory.java
+++ b/sms4j-core/src/main/java/org/dromara/sms4j/core/config/SupplierFactory.java
@@ -1,14 +1,26 @@
package org.dromara.sms4j.core.config;
-import org.dromara.sms4j.comm.enumerate.SupplierType;
-import org.dromara.sms4j.core.factory.SmsFactory;
-import org.dromara.sms4j.emay.config.EmayConfig;
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
+import org.dromara.sms4j.aliyun.config.AlibabaFactory;
+import org.dromara.sms4j.api.universal.SupplierConfig;
import org.dromara.sms4j.cloopen.config.CloopenConfig;
+import org.dromara.sms4j.cloopen.config.CloopenFactory;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.core.factory.SmsFactory;
+import org.dromara.sms4j.ctyun.config.CtyunConfig;
+import org.dromara.sms4j.ctyun.config.CtyunFactory;
+import org.dromara.sms4j.emay.config.EmayConfig;
+import org.dromara.sms4j.emay.config.EmayFactory;
import org.dromara.sms4j.huawei.config.HuaweiConfig;
+import org.dromara.sms4j.huawei.config.HuaweiFactory;
import org.dromara.sms4j.jdcloud.config.JdCloudConfig;
+import org.dromara.sms4j.jdcloud.config.JdCloudFactory;
+import org.dromara.sms4j.provider.enumerate.SupplierType;
import org.dromara.sms4j.tencent.config.TencentConfig;
+import org.dromara.sms4j.tencent.config.TencentFactory;
import org.dromara.sms4j.unisms.config.UniConfig;
+import org.dromara.sms4j.unisms.config.UniFactory;
+import org.dromara.sms4j.yunpian.config.YunPianFactory;
import org.dromara.sms4j.yunpian.config.YunpianConfig;
/**
@@ -21,103 +33,104 @@ public class SupplierFactory {
private SupplierFactory() {
}
- /** 阿里云差异化配置*/
- private static AlibabaConfig alibabaConfig;
-
- /** 华为云差异化配置*/
- private static HuaweiConfig huaweiConfig;
-
- /** 合一短信差异化配置*/
- private static UniConfig uniConfig;
-
- /** 腾讯云短信差异化配置*/
- private static TencentConfig tencentConfig;
-
- /** 云片短信差异配置*/
- private static YunpianConfig yunpianConfig;
-
- /** 京东云短信差异配置 */
- private static JdCloudConfig jdCloudConfig;
-
- /** 容联云短信差异配置 */
- private static CloopenConfig cloopenConfig;
+ /**
+ * 阿里云配置获取
+ */
+ public static AlibabaConfig getAlibabaConfig() {
+ return AlibabaFactory.instance().getConfig();
+ }
/**
- * 亿美软通短信差异配置
+ * 华为云配置获取
*/
- private static EmayConfig emayConfig;
-
- /** 阿里云配置获取*/
- public static AlibabaConfig getAlibabaConfig() {
- if (alibabaConfig == null){
- alibabaConfig = AlibabaConfig.builder().build();
- }
- return alibabaConfig;
- }
-
- /** 华为云配置获取*/
public static HuaweiConfig getHuaweiConfig() {
- if (huaweiConfig == null){
- huaweiConfig = HuaweiConfig.builder().build();
- }
- return huaweiConfig;
+ return HuaweiFactory.instance().getConfig();
}
- /** 合一短信配置获取*/
+ /**
+ * 合一短信配置获取
+ */
public static UniConfig getUniConfig() {
- if (uniConfig == null){
- uniConfig = UniConfig.builder().build();
- }
- return uniConfig;
+ return UniFactory.instance().getConfig();
}
- /** 腾讯短信配置获取*/
+ /**
+ * 腾讯短信配置获取
+ */
public static TencentConfig getTencentConfig() {
- if (tencentConfig == null){
- tencentConfig = TencentConfig.builder().build();
- }
- return tencentConfig;
+ return TencentFactory.instance().getConfig();
}
- /** 云片短信配置获取*/
+ /**
+ * 云片短信配置获取
+ */
public static YunpianConfig getYunpianConfig() {
- if (yunpianConfig == null){
- yunpianConfig = YunpianConfig.builder().build();
- }
- return yunpianConfig;
+ return YunPianFactory.instance().getConfig();
}
- /** 京东云短信配置获取 */
+ /**
+ * 京东云短信配置获取
+ */
public static JdCloudConfig getJdCloudConfig() {
- if (jdCloudConfig == null){
- jdCloudConfig = JdCloudConfig.builder().build();
- }
- return jdCloudConfig;
+ return JdCloudFactory.instance().getConfig();
}
- /** 容联云短信配置获取 */
+ /**
+ * 容联云短信配置获取
+ */
public static CloopenConfig getCloopenConfig() {
- if (cloopenConfig == null){
- cloopenConfig = CloopenConfig.builder().build();
- }
- return cloopenConfig;
+ return CloopenFactory.instance().getConfig();
}
/**
* 亿美软通配置获取
*/
public static EmayConfig getEmayConfig() {
- if (emayConfig == null) {
- emayConfig = EmayConfig.builder().build();
+ return EmayFactory.instance().getConfig();
+ }
+
+ /**
+ * 天翼云配置获取
+ */
+ public static CtyunConfig getCtyunConfig() {
+ return CtyunFactory.instance().getConfig();
+ }
+
+ /**
+ * setSupplierConfig
+ *
通用化set,用于设置
+ * @param t 配置对象
+ * @author :Wind
+ */
+ public static void setSupplierConfig(T t) {
+ if (t instanceof AlibabaConfig) {
+ setAlibabaConfig((AlibabaConfig) t);
+ } else if (t instanceof HuaweiConfig) {
+ setHuaweiConfig((HuaweiConfig) t);
+ } else if (t instanceof UniConfig) {
+ setUniConfig((UniConfig) t);
+ } else if (t instanceof TencentConfig) {
+ setTencentConfig((TencentConfig) t);
+ } else if (t instanceof YunpianConfig) {
+ setYunpianConfig((YunpianConfig) t);
+ } else if (t instanceof JdCloudConfig) {
+ setJdCloudConfig((JdCloudConfig) t);
+ } else if (t instanceof CloopenConfig) {
+ setCloopenConfig((CloopenConfig) t);
+ } else if (t instanceof EmayConfig) {
+ setEmayConfig((EmayConfig) t);
+ } else if (t instanceof CtyunConfig) {
+ setCtyunConfig((CtyunConfig) t);
+ }else {
+ throw new SmsBlendException("Loading failure! Please check the configuration type.");
}
- return emayConfig;
}
/**
* 设置 alibabaConfig
*/
public static void setAlibabaConfig(AlibabaConfig alibabaConfig) {
- SupplierFactory.alibabaConfig = alibabaConfig;
+ AlibabaFactory.instance().setConfig(alibabaConfig);
SmsFactory.refresh(SupplierType.ALIBABA);
}
@@ -125,7 +138,7 @@ public class SupplierFactory {
* 设置 huaweiConfig
*/
public static void setHuaweiConfig(HuaweiConfig huaweiConfig) {
- SupplierFactory.huaweiConfig = huaweiConfig;
+ HuaweiFactory.instance().setConfig(huaweiConfig);
SmsFactory.refresh(SupplierType.HUAWEI);
}
@@ -133,7 +146,7 @@ public class SupplierFactory {
* 设置 uniConfig
*/
public static void setUniConfig(UniConfig uniConfig) {
- SupplierFactory.uniConfig = uniConfig;
+ UniFactory.instance().setConfig(uniConfig);
SmsFactory.refresh(SupplierType.UNI_SMS);
}
@@ -141,7 +154,7 @@ public class SupplierFactory {
* 设置 tencentConfig
*/
public static void setTencentConfig(TencentConfig tencentConfig) {
- SupplierFactory.tencentConfig = tencentConfig;
+ TencentFactory.instance().setConfig(tencentConfig);
SmsFactory.refresh(SupplierType.TENCENT);
}
@@ -149,7 +162,7 @@ public class SupplierFactory {
* 设置 yunpianConfig
*/
public static void setYunpianConfig(YunpianConfig yunpianConfig) {
- SupplierFactory.yunpianConfig = yunpianConfig;
+ YunPianFactory.instance().setConfig(yunpianConfig);
SmsFactory.refresh(SupplierType.YUNPIAN);
}
@@ -157,7 +170,7 @@ public class SupplierFactory {
* 设置 jdCloudConfig
*/
public static void setJdCloudConfig(JdCloudConfig jdCloudConfig) {
- SupplierFactory.jdCloudConfig = jdCloudConfig;
+ JdCloudFactory.instance().setConfig(jdCloudConfig);
SmsFactory.refresh(SupplierType.JD_CLOUD);
}
@@ -165,7 +178,7 @@ public class SupplierFactory {
* 设置 cloopenConfig
*/
public static void setCloopenConfig(CloopenConfig cloopenConfig) {
- SupplierFactory.cloopenConfig = cloopenConfig;
+ CloopenFactory.instance().setConfig(cloopenConfig);
SmsFactory.refresh(SupplierType.CLOOPEN);
}
@@ -173,7 +186,15 @@ public class SupplierFactory {
* 设置 emayConfig
*/
public static void setEmayConfig(EmayConfig emayConfig) {
- SupplierFactory.emayConfig = emayConfig;
+ EmayFactory.instance().setConfig(emayConfig);
SmsFactory.refresh(SupplierType.EMAY);
}
+
+ /**
+ * 设置 ctyunConfig
+ */
+ public static void setCtyunConfig(CtyunConfig ctyunConfig) {
+ CtyunFactory.instance().setConfig(ctyunConfig);
+ SmsFactory.refresh(SupplierType.CTYUN);
+ }
}
diff --git a/sms4j-core/src/main/java/org/dromara/sms4j/core/factory/SmsFactory.java b/sms4j-core/src/main/java/org/dromara/sms4j/core/factory/SmsFactory.java
index 5297c2be..c8ab2825 100644
--- a/sms4j-core/src/main/java/org/dromara/sms4j/core/factory/SmsFactory.java
+++ b/sms4j-core/src/main/java/org/dromara/sms4j/core/factory/SmsFactory.java
@@ -1,17 +1,16 @@
package org.dromara.sms4j.core.factory;
-import org.dromara.sms4j.aliyun.config.AlibabaSmsConfig;
import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.cloopen.config.CloopenSmsConfig;
-import org.dromara.sms4j.comm.enumerate.SupplierType;
-import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.api.smsProxy.SmsInvocationHandler;
+import org.dromara.sms4j.comm.factory.BeanFactory;
import org.dromara.sms4j.core.SupplierSqlConfig;
-import org.dromara.sms4j.core.config.SupplierFactory;
-import org.dromara.sms4j.emay.config.EmaySmsConfig;
-import org.dromara.sms4j.huawei.config.HuaweiSmsConfig;
-import org.dromara.sms4j.jdcloud.config.JdCloudSmsConfig;
-import org.dromara.sms4j.tencent.config.TencentSmsConfig;
-import org.dromara.sms4j.unisms.config.UniSmsConfig;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+import org.dromara.sms4j.provider.enumerate.SupplierType;
+
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
/**
* SmsFactory
@@ -23,6 +22,9 @@ import org.dromara.sms4j.unisms.config.UniSmsConfig;
* 2023/4/8 15:55
**/
public abstract class SmsFactory {
+
+ private static Map beans = new HashMap<>();
+
private SmsFactory() {
}
@@ -34,23 +36,8 @@ public abstract class SmsFactory {
* @author :Wind
*/
public static SmsBlend createSmsBlend(SupplierType supplierType) {
- switch (supplierType) {
- case ALIBABA:
- return AlibabaSmsConfig.createAlibabaSms(SupplierFactory.getAlibabaConfig());
- case HUAWEI:
- return HuaweiSmsConfig.createHuaweiSms(SupplierFactory.getHuaweiConfig());
- case UNI_SMS:
- return UniSmsConfig.createUniSms(SupplierFactory.getUniConfig());
- case TENCENT:
- return TencentSmsConfig.createTencentSms(SupplierFactory.getTencentConfig());
- case JD_CLOUD:
- return JdCloudSmsConfig.createJdCloudSms(SupplierFactory.getJdCloudConfig());
- case CLOOPEN:
- return CloopenSmsConfig.createCloopenSms(SupplierFactory.getCloopenConfig());
- case EMAY:
- return EmaySmsConfig.createEmaySms(SupplierFactory.getEmayConfig());
- }
- throw new SmsBlendException("An attempt to construct a SmsBlend object failed. Please check that the enumeration is valid");
+ BaseProviderFactory providerFactory = supplierType.getProviderFactory();
+ return providerFactory.createSms(providerFactory.getConfig());
}
/**
@@ -61,13 +48,9 @@ public abstract class SmsFactory {
* @author :Wind
*/
public static void refresh() {
- AlibabaSmsConfig.refresh(SupplierFactory.getAlibabaConfig());
- HuaweiSmsConfig.refresh(SupplierFactory.getHuaweiConfig());
- UniSmsConfig.refresh(SupplierFactory.getUniConfig());
- TencentSmsConfig.refresh(SupplierFactory.getTencentConfig());
- JdCloudSmsConfig.refresh(SupplierFactory.getJdCloudConfig());
- CloopenSmsConfig.refresh(SupplierFactory.getCloopenConfig());
- EmaySmsConfig.refresh(SupplierFactory.getEmayConfig());
+ for(SupplierType type : SupplierType.values()) {
+ refresh(type);
+ }
}
/**
@@ -78,31 +61,8 @@ public abstract class SmsFactory {
* @author :Wind
*/
public static void refresh(SupplierType supplierType) {
- switch (supplierType) {
- case ALIBABA:
- AlibabaSmsConfig.refresh(SupplierFactory.getAlibabaConfig());
- break;
- case HUAWEI:
- HuaweiSmsConfig.refresh(SupplierFactory.getHuaweiConfig());
- break;
- case UNI_SMS:
- UniSmsConfig.refresh(SupplierFactory.getUniConfig());
- break;
- case TENCENT:
- TencentSmsConfig.refresh(SupplierFactory.getTencentConfig());
- break;
- case JD_CLOUD:
- JdCloudSmsConfig.refresh(SupplierFactory.getJdCloudConfig());
- break;
- case CLOOPEN:
- CloopenSmsConfig.refresh(SupplierFactory.getCloopenConfig());
- break;
- case EMAY:
- EmaySmsConfig.refresh(SupplierFactory.getEmayConfig());
- break;
- default:
- throw new SmsBlendException("An attempt to construct a SmsBlend object failed. Please check that the enumeration is valid");
- }
+ BaseProviderFactory providerFactory = supplierType.getProviderFactory();
+ providerFactory.refresh(providerFactory.getConfig());
}
/**
@@ -115,4 +75,44 @@ public abstract class SmsFactory {
SupplierSqlConfig.refreshSqlConfig();
}
+
+ /**
+ * getRestrictedSmsBlend
+ * 获取某个厂商的带有短信拦截的实现
+ *
+ * @param supplierType 厂商枚举
+ * @author :Wind
+ */
+ public static SmsBlend getRestrictedSmsBlend(SupplierType supplierType) {
+ SmsBlend smsBlend = beans.get(supplierType);
+ if (Objects.isNull(smsBlend)) {
+ smsBlend = getSmsBlend(supplierType);
+ beans.put(supplierType, smsBlend);
+ }
+ return smsBlend;
+ }
+
+ /**
+ * refreshRestrictedSmsBlend
+ *
刷新带有短信拦截的对象实现
+ * @param supplierType 厂商枚举
+ * @author :Wind
+ */
+ public static void refreshRestrictedSmsBlend(SupplierType supplierType) {
+ refresh(supplierType);
+ beans.put(supplierType,getSmsBlend(supplierType));
+ }
+
+ private static SmsBlend getSmsBlend(SupplierType supplierType) {
+ SmsBlend sms = createSmsBlend(supplierType);
+ SmsInvocationHandler smsInvocationHandler = SmsInvocationHandler.newSmsInvocationHandler(
+ sms,
+ BeanFactory.getSmsConfig()
+ );
+ return (SmsBlend) Proxy.newProxyInstance(
+ sms.getClass().getClassLoader(),
+ new Class[]{SmsBlend.class},
+ smsInvocationHandler
+ );
+ }
}
diff --git a/sms4j-core/src/main/java/org/dromara/sms4j/core/load/SmsLoad.java b/sms4j-core/src/main/java/org/dromara/sms4j/core/load/SmsLoad.java
index e04b0cc0..362c2148 100644
--- a/sms4j-core/src/main/java/org/dromara/sms4j/core/load/SmsLoad.java
+++ b/sms4j-core/src/main/java/org/dromara/sms4j/core/load/SmsLoad.java
@@ -2,7 +2,8 @@ package org.dromara.sms4j.core.load;
import org.dromara.sms4j.api.SmsBlend;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
/**
* SmsLoad
diff --git a/sms4j-core/src/main/resources/application.properties b/sms4j-core/src/main/resources/application.properties
deleted file mode 100644
index 8b137891..00000000
--- a/sms4j-core/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaConfig.java
index b10262d7..2147f3b1 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaConfig.java
@@ -5,13 +5,14 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
+import org.dromara.sms4j.api.universal.SupplierConfig;
import org.dromara.sms4j.comm.config.BaseConfig;
@Data
@SuperBuilder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
-public class AlibabaConfig extends BaseConfig {
+public class AlibabaConfig extends BaseConfig implements SupplierConfig {
/**
* 模板变量名称
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaFactory.java
new file mode 100644
index 00000000..dbe83418
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaFactory.java
@@ -0,0 +1,87 @@
+package org.dromara.sms4j.aliyun.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.aliyun.service.AlibabaSmsImpl;
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+
+
+/**
+ * AlibabaSmsConfig
+ *
阿里巴巴对象建造者
+ *
+ * @author :Wind
+ * 2023/4/8 14:54
+ **/
+@Slf4j
+public class AlibabaFactory implements BaseProviderFactory {
+
+ private static AlibabaSmsImpl alibabaSms;
+
+ private static final AlibabaFactory INSTANCE = new AlibabaFactory();
+
+ private static final class ConfigHolder {
+ private static AlibabaConfig config = AlibabaConfig.builder().build();
+ }
+
+ private AlibabaFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static AlibabaFactory instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * 创建短信实现对象
+ * @param alibabaConfig 短信配置对象
+ * @return 短信实现对象
+ */
+ @Override
+ public AlibabaSmsImpl createSms(AlibabaConfig alibabaConfig) {
+ if (alibabaSms == null) {
+ alibabaSms = new AlibabaSmsImpl(
+ alibabaConfig,
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime());
+ }
+ return alibabaSms;
+ }
+
+ /**
+ * 刷新短信实现对象
+ * @param alibabaConfig 短信配置对象
+ * @return 刷新后的短信实现对象
+ */
+ @Override
+ public AlibabaSmsImpl refresh(AlibabaConfig alibabaConfig) {
+ //重新构造一个实现对象
+ alibabaSms = new AlibabaSmsImpl(
+ alibabaConfig,
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime());
+ return alibabaSms;
+ }
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public AlibabaConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(AlibabaConfig config) {
+ ConfigHolder.config = config;
+ }
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaSmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaSmsConfig.java
deleted file mode 100644
index ce2b6b4d..00000000
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/config/AlibabaSmsConfig.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.dromara.sms4j.aliyun.config;
-
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.sms4j.aliyun.service.AlibabaSmsImpl;
-import org.dromara.sms4j.comm.factory.BeanFactory;
-
-
-/**
- * AlibabaSmsConfig
- * 阿里巴巴对象建造者
- *
- * @author :Wind
- * 2023/4/8 14:54
- **/
-@Slf4j
-public class AlibabaSmsConfig {
-
- private static AlibabaSmsImpl alibabaSms;
-
- private static AlibabaSmsConfig alibabaSmsConfig;
-
- /**
- * getAlibabaSms
- *
建造一个短信实现对像
- *
- * @author :Wind
- */
- public static AlibabaSmsImpl createAlibabaSms(AlibabaConfig alibabaConfig) {
- if (alibabaSmsConfig == null) {
- alibabaSmsConfig = new AlibabaSmsConfig();
- }
- if (alibabaSms == null) {
- alibabaSms = new AlibabaSmsImpl(
- alibabaConfig,
- BeanFactory.getExecutor(),
- BeanFactory.getDelayedTime());
- }
- return alibabaSms;
- }
-
- /**
- * refresh
- *
刷新对象
- *
- * @author :Wind
- */
- public static AlibabaSmsImpl refresh(AlibabaConfig alibabaConfig) {
- // 如果配置对象为空则创建一个
- if (alibabaSmsConfig == null) {
- alibabaSmsConfig = new AlibabaSmsConfig();
- }
- //重新构造一个实现对象
- alibabaSms = new AlibabaSmsImpl(
- alibabaConfig,
- BeanFactory.getExecutor(),
- BeanFactory.getDelayedTime());
- return alibabaSms;
- }
-
- private AlibabaSmsConfig() {
- }
-}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java
index 23f3578c..14b3205f 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java
@@ -1,24 +1,21 @@
package org.dromara.sms4j.aliyun.service;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.dtflys.forest.config.ForestConfiguration;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
import org.dromara.sms4j.aliyun.utils.AliyunUtils;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.callback.CallBack;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
import org.dromara.sms4j.comm.exception.SmsBlendException;
-import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.comm.utils.SmsUtil;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.TimerTask;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReference;
/**
*
类名: AlibabaSmsImpl
@@ -29,27 +26,19 @@ import java.util.concurrent.Executor;
**/
@Slf4j
-public class AlibabaSmsImpl implements SmsBlend {
+public class AlibabaSmsImpl extends AbstractSmsBlend {
private final AlibabaConfig alibabaSmsConfig;
- private final Executor pool;
-
- private final DelayedTime delayed;
-
- private final ForestConfiguration http = BeanFactory.getForestConfiguration();
-
/**
* AlibabaSmsImpl
*
构造器,用于构造短信实现模块
*
* @author :Wind
*/
-
public AlibabaSmsImpl(AlibabaConfig alibabaSmsConfig, Executor pool, DelayedTime delayedTime) {
+ super(pool, delayedTime);
this.alibabaSmsConfig = alibabaSmsConfig;
- this.pool = pool;
- this.delayed = delayedTime;
}
@Override
@@ -63,7 +52,7 @@ public class AlibabaSmsImpl implements SmsBlend {
@Override
@Restricted
public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) {
- String messageStr = JSON.toJSONString(messages);
+ String messageStr = JSONUtil.toJsonStr(messages);
return getSmsResponse(phone, messageStr, templateId);
}
@@ -78,12 +67,12 @@ public class AlibabaSmsImpl implements SmsBlend {
@Override
@Restricted
public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) {
- String messageStr = JSON.toJSONString(messages);
- return getSmsResponse(arrayToString(phones), messageStr, templateId);
+ String messageStr = JSONUtil.toJsonStr(messages);
+ return getSmsResponse(SmsUtil.arrayToString(phones), messageStr, templateId);
}
private SmsResponse getSmsResponse(String phone, String message, String templateId) {
- SmsResponse smsResponse = new SmsResponse();
+ AtomicReference reference = new AtomicReference<>();
String requestUrl;
String paramStr;
try {
@@ -94,100 +83,32 @@ public class AlibabaSmsImpl implements SmsBlend {
throw new SmsBlendException(e.getMessage());
}
log.debug("requestUrl {}", requestUrl);
- http.post(requestUrl)
+ super.http.post(requestUrl)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addBody(paramStr)
.onSuccess(((data, req, res) -> {
- JSONObject jsonBody = res.get(JSONObject.class);
- log.info(jsonBody.toJSONString());
+ reference.set(this.getResponse(res.get(JSONObject.class)));
}))
.onError((ex, req, res) -> {
- JSONObject jsonBody = res.get(JSONObject.class);
- log.info(jsonBody.toJSONString());
+ reference.set(this.getResponse(res.get(JSONObject.class)));
})
.execute();
+ return reference.get();
+ }
+
+ private SmsResponse getResponse(JSONObject resJson) {
+ SmsResponse smsResponse = new SmsResponse();
+ if (resJson == null) {
+ smsResponse.setErrorCode("500");
+ smsResponse.setErrMessage("aliyun send sms response is null.check param");
+ return smsResponse;
+ }
+ smsResponse.setCode(resJson.getStr("Code"));
+ smsResponse.setMessage(resJson.getStr("Message"));
+ if ("OK".equals(smsResponse.getCode())) {
+ smsResponse.setBizId(resJson.getStr("BizId"));
+ }
return smsResponse;
}
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message) {
- pool.execute(() -> {
- sendMessage(phone, message);
- });
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone,templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(() -> {
- sendMessage(phone, templateId, messages);
- });
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, templateId, messages);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, templateId, messages);
- }
- }, delayedTime);
- }
-
- private String arrayToString(List list) {
- StringBuilder sb = new StringBuilder();
- for (String s : list) {
- sb.append(",").append("+86").append(s);
- }
- return sb.substring(1);
- }
-}
+}
\ No newline at end of file
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/utils/AliyunUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/utils/AliyunUtils.java
index 55af6c42..474bfc86 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/utils/AliyunUtils.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/utils/AliyunUtils.java
@@ -1,14 +1,20 @@
package org.dromara.sms4j.aliyun.utils;
-import cn.hutool.core.codec.Base64;
+import cn.hutool.crypto.digest.HMac;
+import cn.hutool.crypto.digest.HmacAlgorithm;
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
import org.dromara.sms4j.comm.constant.Constant;
-import javax.crypto.Mac;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SimpleTimeZone;
+import java.util.TreeMap;
+import java.util.UUID;
/**
* @author Richard
@@ -21,18 +27,18 @@ public class AliyunUtils {
*/
private static final String ALGORITHM = "HMAC-SHA1";
- private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
public static String generateSendSmsRequestUrl(AlibabaConfig alibabaConfig, String message, String phone, String templateId) throws Exception {
// 这里一定要设置GMT时区
- sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
+ SDF.setTimeZone(new SimpleTimeZone(0, "GMT"));
Map paras = new HashMap<>();
// 1. 公共请求参数
paras.put("SignatureMethod", ALGORITHM);
paras.put("SignatureNonce", UUID.randomUUID().toString());
paras.put("AccessKeyId", alibabaConfig.getAccessKeyId());
paras.put("SignatureVersion", "1.0");
- paras.put("Timestamp", sdf.format(new Date()));
+ paras.put("Timestamp", SDF.format(new Date()));
paras.put("Format", "JSON");
paras.put("Action", alibabaConfig.getAction());
paras.put("Version", alibabaConfig.getVersion());
@@ -80,10 +86,8 @@ public class AliyunUtils {
* @param stringToSign 待生成签名的字符串
*/
private static String sign(String accessSecret, String stringToSign) throws Exception {
- Mac mac = Mac.getInstance("HmacSHA1");
- mac.init(new javax.crypto.spec.SecretKeySpec(accessSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
- byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
- return Base64.encode(signData);
+ HMac hMac = new HMac(HmacAlgorithm.HmacSHA1, accessSecret.getBytes());
+ return hMac.digestBase64(stringToSign,StandardCharsets.UTF_8, false);
}
/**
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenConfig.java
index efeefb15..124ff18e 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenConfig.java
@@ -5,6 +5,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
+import org.dromara.sms4j.api.universal.SupplierConfig;
import org.dromara.sms4j.comm.config.BaseConfig;
/**
@@ -17,7 +18,7 @@ import org.dromara.sms4j.comm.config.BaseConfig;
@SuperBuilder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
-public class CloopenConfig extends BaseConfig {
+public class CloopenConfig extends BaseConfig implements SupplierConfig {
/**
* 应用 ID
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenFactory.java
new file mode 100644
index 00000000..04c5f58c
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenFactory.java
@@ -0,0 +1,77 @@
+package org.dromara.sms4j.cloopen.config;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.dromara.sms4j.cloopen.service.CloopenSmsImpl;
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+
+/**
+ * 容联云短信配置
+ *
+ * @author Charles7c
+ * @since 2023/4/10 22:10
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class CloopenFactory implements BaseProviderFactory {
+
+ private static CloopenSmsImpl cloopenSms;
+
+ private static final CloopenFactory INSTANCE = new CloopenFactory();
+
+ private static final class ConfigHolder {
+ private static CloopenConfig config = CloopenConfig.builder().build();
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static CloopenFactory instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * 创建容连云短信实现对象
+ * @param cloopenConfig 短信配置对象
+ * @return 短信实现对象
+ */
+ @Override
+ public CloopenSmsImpl createSms(CloopenConfig cloopenConfig) {
+ if (cloopenSms == null) {
+ cloopenSms = new CloopenSmsImpl(cloopenConfig, BeanFactory.getExecutor(), BeanFactory.getDelayedTime());
+ }
+ return cloopenSms;
+ }
+
+ /**
+ * 刷新容连云短信实现对象
+ * @param cloopenConfig 短信配置对象
+ * @return 刷新后的短信实现对象
+ */
+ @Override
+ public CloopenSmsImpl refresh(CloopenConfig cloopenConfig) {
+ //重新构造一个实现对象
+ cloopenSms = new CloopenSmsImpl(cloopenConfig, BeanFactory.getExecutor(), BeanFactory.getDelayedTime());
+ return cloopenSms;
+ }
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public CloopenConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(CloopenConfig config) {
+ ConfigHolder.config = config;
+ }
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenSmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenSmsConfig.java
deleted file mode 100644
index 31f058fa..00000000
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/config/CloopenSmsConfig.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.dromara.sms4j.cloopen.config;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.dromara.sms4j.cloopen.service.CloopenSmsImpl;
-import org.dromara.sms4j.comm.factory.BeanFactory;
-
-/**
- * 容联云短信配置
- *
- * @author Charles7c
- * @since 2023/4/10 22:10
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class CloopenSmsConfig {
-
- private static CloopenSmsImpl cloopenSms;
-
- private static CloopenSmsConfig cloopenSmsConfig;
-
- /**
- * 创建容联云短信实现
- */
- public static CloopenSmsImpl createCloopenSms(CloopenConfig cloopenConfig) {
- if (cloopenSmsConfig == null) {
- cloopenSmsConfig = new CloopenSmsConfig();
- }
- if (cloopenSms == null) {
- cloopenSms = new CloopenSmsImpl(cloopenConfig, BeanFactory.getExecutor(), BeanFactory.getDelayedTime());
- }
- return cloopenSms;
- }
-
- /**
- * 刷新对象
- */
- public static CloopenSmsImpl refresh(CloopenConfig cloopenConfig) {
- if (cloopenSmsConfig == null) {
- cloopenSmsConfig = new CloopenSmsConfig();
- }
- cloopenSms = new CloopenSmsImpl(cloopenConfig, BeanFactory.getExecutor(), BeanFactory.getDelayedTime());
- return cloopenSms;
- }
-}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/service/CloopenSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/service/CloopenSmsImpl.java
index 29c45ee7..32ca6af6 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/service/CloopenSmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/service/CloopenSmsImpl.java
@@ -4,8 +4,7 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.dtflys.forest.Forest;
import lombok.extern.slf4j.Slf4j;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.callback.CallBack;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.cloopen.api.CloopenRestApi;
import org.dromara.sms4j.cloopen.config.CloopenConfig;
@@ -13,8 +12,10 @@ import org.dromara.sms4j.cloopen.util.CloopenHelper;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.Executor;
/**
@@ -24,20 +25,15 @@ import java.util.concurrent.Executor;
* @since 2023/4/10 22:10
*/
@Slf4j
-public class CloopenSmsImpl implements SmsBlend {
+public class CloopenSmsImpl extends AbstractSmsBlend {
private final CloopenRestApi restApi;
private final CloopenConfig config;
- private final Executor pool;
-
- private final DelayedTime delayed;
-
public CloopenSmsImpl(CloopenConfig config, Executor pool, DelayedTime delayed) {
+ super(pool,delayed);
this.config = config;
- this.pool = pool;
- this.delayed = delayed;
restApi = Forest.client(CloopenRestApi.class);
}
@@ -72,74 +68,4 @@ public class CloopenSmsImpl implements SmsBlend {
paramMap.put("datas", messages.keySet().stream().map(messages::get).toArray(String[]::new));
return helper.request(restApi::sendSms, paramMap);
}
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message) {
- pool.execute(() -> sendMessage(phone, message));
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone,templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(() -> sendMessage(phone, templateId, messages));
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, templateId, messages);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, templateId, messages);
- }
- }, delayedTime);
- }
}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/config/CtyunConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/config/CtyunConfig.java
new file mode 100644
index 00000000..5c818247
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/config/CtyunConfig.java
@@ -0,0 +1,40 @@
+package org.dromara.sms4j.ctyun.config;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import lombok.experimental.SuperBuilder;
+import org.dromara.sms4j.api.universal.SupplierConfig;
+import org.dromara.sms4j.comm.config.BaseConfig;
+
+/**
+ * 类名: CtyunConfig
+ *
说明: 天翼云短信差异配置
+ *
+ * @author :bleachhtred
+ * 2023/5/12 15:06
+ **/
+@Data
+@SuperBuilder
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class CtyunConfig extends BaseConfig implements SupplierConfig {
+
+ /**
+ * 模板变量名称
+ */
+ private String templateName;
+
+ /**
+ * 请求地址
+ */
+ @Builder.Default
+ private String requestUrl = "https://sms-global.ctapi.ctyun.cn/sms/api/v1";
+
+ /**
+ * 接口名称
+ */
+ @Builder.Default
+ private String action = "SendSms";
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/config/CtyunFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/config/CtyunFactory.java
new file mode 100644
index 00000000..bfb77d44
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/config/CtyunFactory.java
@@ -0,0 +1,87 @@
+package org.dromara.sms4j.ctyun.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.ctyun.service.CtyunSmsImpl;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+
+/**
+ *
类名: CtyunSmsConfig
+ *
说明: 天翼云 云通信短信配置器
+ *
+ * @author :bleachhtred
+ * 2023/5/12 15:06
+ **/
+@Slf4j
+public class CtyunFactory implements BaseProviderFactory {
+
+ private static CtyunSmsImpl ctyunSms;
+
+ private static final CtyunFactory INSTANCE = new CtyunFactory();
+
+ private static final class ConfigHolder {
+ private static CtyunConfig config = CtyunConfig.builder().build();
+ }
+
+ private CtyunFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static CtyunFactory instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * getCtyunSms
+ * 建造一个短信实现对像
+ *
+ * @author :bleachhtred
+ */
+ @Override
+ public CtyunSmsImpl createSms(CtyunConfig ctyunConfig) {
+ if (ctyunSms == null) {
+ ctyunSms = new CtyunSmsImpl(
+ ctyunConfig,
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime());
+ }
+ return ctyunSms;
+ }
+
+ /**
+ * refresh
+ *
刷新对象
+ *
+ * @author :bleachhtred
+ */
+ @Override
+ public CtyunSmsImpl refresh(CtyunConfig ctyunConfig) {
+ //重新构造一个实现对象
+ ctyunSms = new CtyunSmsImpl(
+ ctyunConfig,
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime());
+ return ctyunSms;
+ }
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public CtyunConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(CtyunConfig config) {
+ ConfigHolder.config = config;
+ }
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/service/CtyunSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/service/CtyunSmsImpl.java
new file mode 100644
index 00000000..f8bc710c
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/service/CtyunSmsImpl.java
@@ -0,0 +1,101 @@
+package org.dromara.sms4j.ctyun.service;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.AbstractSmsBlend;
+import org.dromara.sms4j.api.entity.SmsResponse;
+import org.dromara.sms4j.comm.annotation.Restricted;
+import org.dromara.sms4j.comm.delayedTime.DelayedTime;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.comm.utils.SmsUtil;
+import org.dromara.sms4j.ctyun.config.CtyunConfig;
+import org.dromara.sms4j.ctyun.utils.CtyunUtils;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ *
类名: CtyunSmsImpl
+ *
说明: 天翼云短信实现
+ *
+ * @author :bleachhtred
+ * 2023/5/12 15:06
+ **/
+@Slf4j
+public class CtyunSmsImpl extends AbstractSmsBlend {
+
+ private final CtyunConfig ctyunConfig;
+
+
+ public CtyunSmsImpl(CtyunConfig ctyunConfig, Executor pool, DelayedTime delayedTime) {
+ super(pool, delayedTime);
+ this.ctyunConfig = ctyunConfig;
+ }
+
+ @Override
+ @Restricted
+ public SmsResponse sendMessage(String phone, String message) {
+ LinkedHashMap map = new LinkedHashMap<>();
+ map.put(ctyunConfig.getTemplateName(), message);
+ return sendMessage(phone, ctyunConfig.getTemplateId(), map);
+ }
+
+ @Override
+ @Restricted
+ public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) {
+ String messageStr = JSONUtil.toJsonStr(messages);
+ return getSmsResponse(phone, messageStr, templateId);
+ }
+
+ @Override
+ @Restricted
+ public SmsResponse massTexting(List phones, String message) {
+ LinkedHashMap map = new LinkedHashMap<>();
+ map.put(ctyunConfig.getTemplateName(), message);
+ return massTexting(phones, ctyunConfig.getTemplateId(), map);
+ }
+
+ @Override
+ @Restricted
+ public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) {
+ String messageStr = JSONUtil.toJsonStr(messages);
+ return getSmsResponse(SmsUtil.arrayToString(phones), messageStr, templateId);
+ }
+
+ private SmsResponse getSmsResponse(String phone, String message, String templateId) {
+ AtomicReference smsResponse = new AtomicReference<>();
+ String requestUrl;
+ String paramStr;
+ try {
+ requestUrl = ctyunConfig.getRequestUrl();
+ paramStr = CtyunUtils.generateParamJsonStr(ctyunConfig, phone, message, templateId);
+ } catch (Exception e) {
+ log.error("ctyun send message error", e);
+ throw new SmsBlendException(e.getMessage());
+ }
+ log.debug("requestUrl {}", requestUrl);
+ http.post(requestUrl)
+ .addHeader(CtyunUtils.signHeader(paramStr, ctyunConfig.getAccessKeyId(), ctyunConfig.getAccessKeySecret()))
+ .addBody(paramStr)
+ .onSuccess(((data, req, res) -> {
+ smsResponse.set(this.getResponse(res.get(JSONObject.class)));
+ }))
+ .onError((ex, req, res) -> {
+ smsResponse.set(this.getResponse(res.get(JSONObject.class)));
+ })
+ .execute();
+ return smsResponse.get();
+ }
+
+ private SmsResponse getResponse(JSONObject resJson) {
+ SmsResponse smsResponse = new SmsResponse();
+ smsResponse.setCode(resJson.getStr("code"));
+ smsResponse.setMessage(resJson.getStr("message"));
+ smsResponse.setBizId(resJson.getStr("requestId"));
+ return smsResponse;
+ }
+
+}
\ No newline at end of file
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/utils/CtyunUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/utils/CtyunUtils.java
new file mode 100644
index 00000000..c7880640
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/utils/CtyunUtils.java
@@ -0,0 +1,118 @@
+package org.dromara.sms4j.ctyun.utils;
+
+import cn.hutool.crypto.digest.HMac;
+import cn.hutool.crypto.digest.HmacAlgorithm;
+import cn.hutool.json.JSONUtil;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.ctyun.config.CtyunConfig;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Base64;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class CtyunUtils {
+
+ /**
+ * 获取签名时间戳
+ */
+ private static String signatureTime(){
+ SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
+ return timeFormat.format(new Date());
+ }
+
+ /**
+ * 获取签名请求头
+ */
+ public static Map signHeader(String body, String key, String secret){
+ Map map = new ConcurrentHashMap<>();
+
+ // 构造时间戳
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ Date now = new Date();
+ String signatureDate = dateFormat.format(now);
+ String signatureTime = signatureTime();
+ // 构造请求流水号
+ String uuid = UUID.randomUUID().toString();
+
+ String calculateContentHash = getSHA256(body);
+
+ byte[] kTime = hmacSHA256(signatureTime.getBytes(), secret.getBytes());
+ byte[] kAk = hmacSHA256(key.getBytes(), kTime);
+ byte[] kDate = hmacSHA256(signatureDate.getBytes(), kAk);
+
+ // 构造待签名字符串
+
+ // 报文原封不动进行sha256摘要
+ String signatureStr = String.format("ctyun-eop-request-id:%s\neop-date:%s\n", uuid, signatureTime) + "\n\n" + calculateContentHash;
+ // 构造签名
+ String signature = Base64.getEncoder().encodeToString(hmacSHA256(signatureStr.getBytes(StandardCharsets.UTF_8), kDate));
+ String signHeader = String.format("%s Headers=ctyun-eop-request-id;eop-date Signature=%s", key, signature);
+ map.put("Content-Type", "application/json;charset=UTF-8");
+ map.put("ctyun-eop-request-id", uuid);
+ map.put("Eop-date", signatureTime);
+ map.put("Eop-Authorization", signHeader);
+ return map;
+ }
+
+ /**
+ * 生成请求body参数
+ *
+ * @param ctyunConfig 配置数据
+ * @param phone 手机号
+ * @param message 短信内容
+ * @param templateId 模板id
+ */
+ public static String generateParamJsonStr(CtyunConfig ctyunConfig, String phone, String message, String templateId) {
+ Map paramMap = new HashMap<>();
+ paramMap.put("action", ctyunConfig.getAction());
+ paramMap.put("phoneNumber", phone);
+ paramMap.put("signName", ctyunConfig.getSignature());
+ paramMap.put("templateParam", message);
+ paramMap.put("templateCode", templateId);
+ return JSONUtil.toJsonStr(paramMap);
+ }
+
+ private static String toHex(byte[] data) {
+ StringBuilder sb = new StringBuilder(data.length * 2);
+ for (byte b : data) {
+ String hex = Integer.toHexString(b);
+ if (hex.length() == 1) {
+ sb.append("0");
+ } else if (hex.length() == 8) {
+ hex = hex.substring(6);
+ }
+ sb.append(hex);
+ }
+ return sb.toString().toLowerCase(Locale.getDefault());
+ }
+
+ private static String getSHA256(String text) {
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ md.update(text.getBytes(StandardCharsets.UTF_8));
+ return toHex(md.digest());
+ } catch (NoSuchAlgorithmException var3) {
+ return null;
+ }
+ }
+
+ private static byte[] hmacSHA256(byte[] data, byte[] key){
+ try {
+ HMac hMac = new HMac(HmacAlgorithm.HmacSHA256, key);
+ return hMac.digest(data);
+ } catch (Exception e) {
+ throw new SmsBlendException(e.getMessage());
+ }
+ }
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmayConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmayConfig.java
index e9d273af..f91868ab 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmayConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmayConfig.java
@@ -2,6 +2,7 @@ package org.dromara.sms4j.emay.config;
import lombok.Builder;
import lombok.Data;
+import org.dromara.sms4j.api.universal.SupplierConfig;
/**
* @author Richard
@@ -9,7 +10,7 @@ import lombok.Data;
*/
@Data
@Builder
-public class EmayConfig {
+public class EmayConfig implements SupplierConfig {
/** appKey*/
private String appId ;
/** appSecret */
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmayFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmayFactory.java
new file mode 100644
index 00000000..3ccd9720
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmayFactory.java
@@ -0,0 +1,75 @@
+package org.dromara.sms4j.emay.config;
+
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.emay.service.EmaySmsImpl;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+
+/**
+ * EmaySmsConfig
+ * Emay短信对象建造
+ *
+ * @author Richard
+ * @date 2023/04/11 12:00
+ * */
+public class EmayFactory implements BaseProviderFactory {
+ private static EmaySmsImpl emaySms;
+ private static final EmayFactory INSTANCE = new EmayFactory();
+
+ private static final class ConfigHolder {
+ private static EmayConfig config = EmayConfig.builder().build();
+ }
+
+ private EmayFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static EmayFactory instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * 创建亿美软通短信实现对象
+ * @param emayConfig 短信配置对象
+ * @return 短信实现对象
+ */
+ @Override
+ public EmaySmsImpl createSms(EmayConfig emayConfig) {
+ if (emaySms == null){
+ emaySms = new EmaySmsImpl(emayConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
+ }
+ return emaySms;
+ }
+
+ /**
+ * 刷新短信实现对象
+ * @param emayConfig 短信配置对象
+ * @return 刷新后的短信实现对象
+ */
+ @Override
+ public EmaySmsImpl refresh(EmayConfig emayConfig){
+ emaySms = new EmaySmsImpl(emayConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
+ return emaySms;
+ }
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public EmayConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(EmayConfig config) {
+ ConfigHolder.config = config;
+ }
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmaySmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmaySmsConfig.java
deleted file mode 100644
index d9c7db2e..00000000
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/config/EmaySmsConfig.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.dromara.sms4j.emay.config;
-
-import org.dromara.sms4j.emay.service.EmaySmsImpl;
-import org.dromara.sms4j.comm.factory.BeanFactory;
-
-/**
- * EmaySmsConfig
- * Emay短信对象建造
- *
- * @author Richard
- * @date 2023/04/11 12:00
- * */
-public class EmaySmsConfig {
- private static EmaySmsImpl emaySms;
- private static EmaySmsConfig emaySmsConfig;
-
- private EmaySmsConfig() {
- }
-
- /** 建造一个亿美软通短信实现*/
- public static EmaySmsImpl createEmaySms(EmayConfig emayConfig) {
- if (emaySmsConfig == null){
- emaySmsConfig = new EmaySmsConfig();
- }
- if (emaySms == null){
- emaySms = new EmaySmsImpl(emayConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
- }
- return emaySms;
- }
-
- /** 刷新对象*/
- public static EmaySmsImpl refresh(EmayConfig emayConfig){
- if (emaySmsConfig == null){
- emaySmsConfig = new EmaySmsConfig();
- }
- emaySms = new EmaySmsImpl(emayConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
- return emaySms;
- }
-
-}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java
index 4c96c7e0..9e6cb7e0 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java
@@ -1,45 +1,38 @@
package org.dromara.sms4j.emay.service;
-import com.alibaba.fastjson.JSONObject;
-import com.dtflys.forest.config.ForestConfiguration;
-import org.dromara.sms4j.emay.config.EmayConfig;
-import org.dromara.sms4j.emay.util.EmayBuilder;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.callback.CallBack;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
import org.dromara.sms4j.comm.exception.SmsBlendException;
-import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.comm.utils.SmsUtil;
+import org.dromara.sms4j.emay.config.EmayConfig;
+import org.dromara.sms4j.emay.util.EmayBuilder;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
-import static org.dromara.sms4j.comm.utils.SmsUtil.listToString;
/**
* @author Richard
* @date 2023-04-11 12:00
*/
@Slf4j
-public class EmaySmsImpl implements SmsBlend {
+public class EmaySmsImpl extends AbstractSmsBlend {
public EmaySmsImpl(EmayConfig config, Executor pool, DelayedTime delayed) {
+ super(pool, delayed);
this.config = config;
- this.pool = pool;
- this.delayed = delayed;
}
private EmayConfig config;
- private Executor pool;
-
- private DelayedTime delayed;
-
- private final ForestConfiguration http = BeanFactory.getForestConfiguration();
-
@Override
@Restricted
public SmsResponse sendMessage(String phone, String message) {
@@ -71,7 +64,7 @@ public class EmaySmsImpl implements SmsBlend {
if (phones.size() > 500) {
throw new SmsBlendException("单次发送超过最大发送上限,建议每次群发短信人数低于500");
}
- return sendMessage(listToString(phones), message);
+ return sendMessage(SmsUtil.listToString(phones), message);
}
@Override
@@ -84,77 +77,7 @@ public class EmaySmsImpl implements SmsBlend {
for (Map.Entry entry : messages.entrySet()) {
list.add(entry.getValue());
}
- return sendMessage(listToString(phones), EmayBuilder.listToString(list));
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message) {
- pool.execute(() -> sendMessage(phone, message));
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(() -> sendMessage(phone, templateId, messages));
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, templateId, messages);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, templateId, messages);
- }
- }, delayedTime);
+ return sendMessage(SmsUtil.listToString(phones), EmayBuilder.listToString(list));
}
private SmsResponse getSendResponse(Map body, String requestUrl) {
@@ -177,14 +100,25 @@ public class EmaySmsImpl implements SmsBlend {
private static SmsResponse getSmsResponse(JSONObject execute) {
SmsResponse smsResponse = new SmsResponse();
- String code = execute.getString("code");
- smsResponse.setCode(code);
- if ("success".equalsIgnoreCase(code)) {
- JSONObject data = execute.getJSONObject("data");
- String smsId = data.getString("smsId");
- smsResponse.setBizId(smsId);
+ if (execute == null) {
+ smsResponse.setErrorCode("500");
+ smsResponse.setErrMessage("emay send sms response is null.check param");
+ return smsResponse;
+ }
+ String code = execute.getStr("code");
+ if (SmsUtil.isEmpty(code)) {
+ smsResponse.setErrorCode("emay response code is null");
+ smsResponse.setErrMessage("emay is error");
+ } else {
+ smsResponse.setCode(code);
+ if ("success".equalsIgnoreCase(code)) {
+ JSONArray data = execute.getJSONArray("data");
+ JSONObject result = (JSONObject) data.get(0);
+ String smsId = result.getStr("smsId");
+ smsResponse.setBizId(smsId);
+ }
+ smsResponse.setData(execute);
}
- smsResponse.setData(execute);
return smsResponse;
}
}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiConfig.java
index ba2e9f5a..a11a8902 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiConfig.java
@@ -2,10 +2,11 @@ package org.dromara.sms4j.huawei.config;
import lombok.Builder;
import lombok.Data;
+import org.dromara.sms4j.api.universal.SupplierConfig;
@Data
@Builder
-public class HuaweiConfig {
+public class HuaweiConfig implements SupplierConfig {
/** appKey*/
private String appKey ;
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiFactory.java
new file mode 100644
index 00000000..6b62aef6
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiFactory.java
@@ -0,0 +1,67 @@
+package org.dromara.sms4j.huawei.config;
+
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.huawei.service.HuaweiSmsImpl;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+
+/**
+ * HuaweiSmsConfig
+ * 华为短信对象建造
+ *
+ * @author :Wind
+ * 2023/4/8 15:27
+ **/
+public class HuaweiFactory implements BaseProviderFactory {
+ private static HuaweiSmsImpl huaweiSms;
+ private static final HuaweiFactory INSTANCE = new HuaweiFactory();
+
+ private static final class ConfigHolder {
+ private static HuaweiConfig config = HuaweiConfig.builder().build();
+ }
+
+ private HuaweiFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static HuaweiFactory instance() {
+ return INSTANCE;
+ }
+
+ /** 建造一个华为短信实现*/
+ @Override
+ public HuaweiSmsImpl createSms(HuaweiConfig huaweiConfig) {
+ if (huaweiSms == null){
+ huaweiSms = new HuaweiSmsImpl(huaweiConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
+ }
+ return huaweiSms;
+ }
+
+ /** 刷新对象*/
+ @Override
+ public HuaweiSmsImpl refresh(HuaweiConfig huaweiConfig){
+ huaweiSms = new HuaweiSmsImpl(huaweiConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
+ return huaweiSms;
+ }
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public HuaweiConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(HuaweiConfig config) {
+ ConfigHolder.config = config;
+ }
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiSmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiSmsConfig.java
deleted file mode 100644
index 3aed8b40..00000000
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/config/HuaweiSmsConfig.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.dromara.sms4j.huawei.config;
-import org.dromara.sms4j.comm.factory.BeanFactory;
-import org.dromara.sms4j.huawei.service.HuaweiSmsImpl;
-
-/**
- * HuaweiSmsConfig
- * 华为短信对象建造
- *
- * @author :Wind
- * 2023/4/8 15:27
- **/
-public class HuaweiSmsConfig {
- private static HuaweiSmsImpl huaweiSms;
- private static HuaweiSmsConfig huaweiSmsConfig;
-
- private HuaweiSmsConfig() {
- }
-
- /** 建造一个华为短信实现*/
- public static HuaweiSmsImpl createHuaweiSms(HuaweiConfig huaweiConfig) {
- if (huaweiSmsConfig == null){
- huaweiSmsConfig = new HuaweiSmsConfig();
- }
- if (huaweiSms == null){
- huaweiSms = new HuaweiSmsImpl(huaweiConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
- }
- return huaweiSms;
- }
-
- /** 刷新对象*/
- public static HuaweiSmsImpl refresh(HuaweiConfig huaweiConfig){
- if (huaweiSmsConfig == null){
- huaweiSmsConfig = new HuaweiSmsConfig();
- }
- huaweiSms = new HuaweiSmsImpl(huaweiConfig, BeanFactory.getExecutor(),BeanFactory.getDelayedTime());
- return huaweiSms;
- }
-
-}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/entity/SmsId.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/entity/SmsId.java
index 185611d3..197e6bf4 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/entity/SmsId.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/entity/SmsId.java
@@ -2,8 +2,6 @@ package org.dromara.sms4j.huawei.entity;
import lombok.Data;
-import java.util.Date;
-
/**
* SmsId
*
短信ID列表
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java
index 971f98c9..6321a19b 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java
@@ -1,48 +1,40 @@
package org.dromara.sms4j.huawei.service;
-import com.dtflys.forest.config.ForestConfiguration;
-
-import org.dromara.sms4j.api.callback.CallBack;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.constant.Constant;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
-import org.dromara.sms4j.comm.factory.BeanFactory;
import org.dromara.sms4j.huawei.config.HuaweiConfig;
import org.dromara.sms4j.huawei.entity.HuaweiResponse;
import org.dromara.sms4j.huawei.utils.HuaweiBuilder;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.sms4j.api.SmsBlend;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.Executor;
import static org.dromara.sms4j.huawei.utils.HuaweiBuilder.listToString;
@Slf4j
-public class HuaweiSmsImpl implements SmsBlend {
+public class HuaweiSmsImpl extends AbstractSmsBlend {
public HuaweiSmsImpl(HuaweiConfig config, Executor pool, DelayedTime delayed) {
+ super(pool,delayed);
this.config = config;
- this.pool = pool;
- this.delayed = delayed;
}
private HuaweiConfig config;
- private Executor pool;
-
- private DelayedTime delayed;
-
- private final ForestConfiguration http = BeanFactory.getForestConfiguration();
-
@Override
@Restricted
public SmsResponse sendMessage(String phone, String message) {
- LinkedHashMap mes = new LinkedHashMap<>();
- mes.put(UUID.randomUUID().toString().replaceAll("-",""),message);
- return sendMessage(phone,config.getTemplateId(),mes);
+ LinkedHashMap mes = new LinkedHashMap<>();
+ mes.put(UUID.randomUUID().toString().replaceAll("-", ""), message);
+ return sendMessage(phone, config.getTemplateId(), mes);
}
@Override
@@ -55,26 +47,30 @@ public class HuaweiSmsImpl implements SmsBlend {
}
String mess = listToString(list);
String requestBody = HuaweiBuilder.buildRequestBody(config.getSender(), phone, templateId, mess, config.getStatusCallBack(), config.getSignature());
- Map headers = new LinkedHashMap<>();
- headers.put("Authorization",Constant.HUAWEI_AUTH_HEADER_VALUE);
- headers.put("X-WSSE",HuaweiBuilder.buildWsseHeader(config.getAppKey(), config.getAppSecret()));
- headers.put("Content-Type",Constant.FROM_URLENCODED);
+ Map headers = new LinkedHashMap<>();
+ headers.put("Authorization", Constant.HUAWEI_AUTH_HEADER_VALUE);
+ headers.put("X-WSSE", HuaweiBuilder.buildWsseHeader(config.getAppKey(), config.getAppSecret()));
+ headers.put("Content-Type", Constant.FROM_URLENCODED);
SmsResponse smsResponse = new SmsResponse();
http.post(url)
.addHeader(headers)
.addBody(requestBody)
- .onSuccess(((data,req,res)->{
+ .onSuccess(((data, req, res) -> {
HuaweiResponse jsonBody = res.get(HuaweiResponse.class);
smsResponse.setCode(jsonBody.getCode());
smsResponse.setMessage(jsonBody.getDescription());
smsResponse.setBizId(jsonBody.getResult().get(0).getSmsMsgId());
smsResponse.setData(jsonBody.getResult());
}))
- .onError((ex,req,res)->{
+ .onError((ex, req, res) -> {
HuaweiResponse huaweiResponse = res.get(HuaweiResponse.class);
- smsResponse.setErrMessage(huaweiResponse.getDescription());
- smsResponse.setErrorCode(huaweiResponse.getCode());
- log.debug(huaweiResponse.getDescription());
+ if (huaweiResponse == null) {
+ smsResponse.setErrorCode("500");
+ smsResponse.setErrMessage("huawei send sms response is null.check param");
+ } else {
+ smsResponse.setErrMessage(huaweiResponse.getDescription());
+ smsResponse.setErrorCode(huaweiResponse.getCode());
+ }
})
.execute();
return smsResponse;
@@ -83,7 +79,7 @@ public class HuaweiSmsImpl implements SmsBlend {
@Override
@Restricted
public SmsResponse massTexting(List phones, String message) {
- return sendMessage(listToString(phones),message);
+ return sendMessage(listToString(phones), message);
}
@Override
@@ -91,76 +87,4 @@ public class HuaweiSmsImpl implements SmsBlend {
public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) {
return sendMessage(listToString(phones), templateId, messages);
}
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message) {
- pool.execute(() -> sendMessage(phone, message));
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(() -> {
- sendMessage(phone, templateId, messages);
- });
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, templateId, messages);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, templateId, messages);
- }
- }, delayedTime);
- }
}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/utils/HuaweiBuilder.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/utils/HuaweiBuilder.java
index 27a05b14..462100ff 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/utils/HuaweiBuilder.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/utils/HuaweiBuilder.java
@@ -14,7 +14,12 @@ import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Base64;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
public class HuaweiBuilder {
private HuaweiBuilder(){}
@@ -122,8 +127,9 @@ public class HuaweiBuilder {
stringBuffer.append(s);
stringBuffer.append("\"");
stringBuffer.append(",");
+ stringBuffer.append("\"");
}
- stringBuffer.deleteCharAt(stringBuffer.length()-1);
+ stringBuffer.delete(stringBuffer.length()-3,stringBuffer.length()-1);
stringBuffer.append("]");
return stringBuffer.toString();
}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudConfig.java
index 5fbc6f70..af179568 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudConfig.java
@@ -5,6 +5,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
+import org.dromara.sms4j.api.universal.SupplierConfig;
import org.dromara.sms4j.comm.config.BaseConfig;
/**
@@ -17,7 +18,7 @@ import org.dromara.sms4j.comm.config.BaseConfig;
@SuperBuilder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
-public class JdCloudConfig extends BaseConfig {
+public class JdCloudConfig extends BaseConfig implements SupplierConfig {
/**
* 地域信息
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudSmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudFactory.java
similarity index 58%
rename from sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudSmsConfig.java
rename to sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudFactory.java
index cf29b5ca..5c3cde20 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudSmsConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/config/JdCloudFactory.java
@@ -7,6 +7,7 @@ import com.jdcloud.sdk.http.Protocol;
import com.jdcloud.sdk.service.sms.client.SmsClient;
import org.dromara.sms4j.comm.factory.BeanFactory;
import org.dromara.sms4j.jdcloud.service.JdCloudSmsImpl;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
/**
* 京东云短信配置
@@ -14,11 +15,26 @@ import org.dromara.sms4j.jdcloud.service.JdCloudSmsImpl;
* @author Charles7c
* @since 2023/4/10 20:01
*/
-public class JdCloudSmsConfig {
+public class JdCloudFactory implements BaseProviderFactory {
private static JdCloudSmsImpl jdCloudSms;
- private static JdCloudSmsConfig jdCloudSmsConfig;
+ private static final JdCloudFactory INSTANCE = new JdCloudFactory();
+
+ private static final class ConfigHolder {
+ private static JdCloudConfig config = JdCloudConfig.builder().build();
+ }
+
+ private JdCloudFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static JdCloudFactory instance() {
+ return INSTANCE;
+ }
/**
* 客户端对象
@@ -36,13 +52,11 @@ public class JdCloudSmsConfig {
/**
* 创建京东云短信实现
*/
- public static JdCloudSmsImpl createJdCloudSms(JdCloudConfig jdCloudConfig) {
- if (jdCloudSmsConfig == null) {
- jdCloudSmsConfig = new JdCloudSmsConfig();
- }
+ @Override
+ public JdCloudSmsImpl createSms(JdCloudConfig jdCloudConfig) {
if (jdCloudSms == null) {
jdCloudSms = new JdCloudSmsImpl(
- jdCloudSmsConfig.client(jdCloudConfig),
+ this.client(jdCloudConfig),
jdCloudConfig,
BeanFactory.getExecutor(),
BeanFactory.getDelayedTime()
@@ -54,16 +68,33 @@ public class JdCloudSmsConfig {
/**
* 刷新对象
*/
- public static JdCloudSmsImpl refresh(JdCloudConfig jdCloudConfig) {
- if (jdCloudSmsConfig == null) {
- jdCloudSmsConfig = new JdCloudSmsConfig();
- }
+ @Override
+ public JdCloudSmsImpl refresh(JdCloudConfig jdCloudConfig) {
jdCloudSms = new JdCloudSmsImpl(
- jdCloudSmsConfig.client(jdCloudConfig),
+ this.client(jdCloudConfig),
jdCloudConfig,
BeanFactory.getExecutor(),
BeanFactory.getDelayedTime()
);
return jdCloudSms;
}
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public JdCloudConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(JdCloudConfig config) {
+ ConfigHolder.config = config;
+ }
+
}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java
index 5a7c94e0..54f0d846 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java
@@ -5,8 +5,7 @@ import com.jdcloud.sdk.service.sms.client.SmsClient;
import com.jdcloud.sdk.service.sms.model.BatchSendRequest;
import com.jdcloud.sdk.service.sms.model.BatchSendResult;
import lombok.extern.slf4j.Slf4j;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.callback.CallBack;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
@@ -16,8 +15,6 @@ import org.dromara.sms4j.jdcloud.config.JdCloudConfig;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.TimerTask;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
@@ -28,21 +25,16 @@ import java.util.stream.Collectors;
* @since 2023/4/10 20:01
*/
@Slf4j
-public class JdCloudSmsImpl implements SmsBlend {
+public class JdCloudSmsImpl extends AbstractSmsBlend {
private final SmsClient client;
private final JdCloudConfig config;
- private final Executor pool;
-
- private final DelayedTime delayed;
-
public JdCloudSmsImpl(SmsClient client, JdCloudConfig config, Executor pool, DelayedTime delayed) {
+ super(pool,delayed);
this.client = client;
this.config = config;
- this.pool = pool;
- this.delayed = delayed;
}
@Override
@@ -85,76 +77,6 @@ public class JdCloudSmsImpl implements SmsBlend {
}
}
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message) {
- pool.execute(() -> sendMessage(phone, message));
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(() -> sendMessage(phone, templateId, messages));
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, templateId, messages);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, templateId, messages);
- }
- }, delayedTime);
- }
-
/**
* 获取短信返回信息
*
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/base/BaseProviderFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/base/BaseProviderFactory.java
new file mode 100644
index 00000000..42dd2508
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/base/BaseProviderFactory.java
@@ -0,0 +1,40 @@
+package org.dromara.sms4j.provider.base;
+
+import org.dromara.sms4j.api.SmsBlend;
+import org.dromara.sms4j.api.universal.SupplierConfig;
+
+/**
+ * AlibabaSmsConfig
+ * 短信对象建造者
+ * @param 短信对象
+ * @param 短信配置对象
+ */
+public interface BaseProviderFactory {
+
+ /**
+ * 创建短信实现对象
+ * @param c 短信配置对象
+ * @return 短信实现对象
+ */
+ S createSms(C c);
+
+ /**
+ * 刷新短信实现对象
+ * @param c 短信配置对象
+ * @return 刷新后的短信实现对象
+ */
+ S refresh(C c);
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ C getConfig();
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ void setConfig(C config);
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/enumerate/SupplierType.java b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/enumerate/SupplierType.java
new file mode 100644
index 00000000..9725047c
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/enumerate/SupplierType.java
@@ -0,0 +1,66 @@
+package org.dromara.sms4j.provider.enumerate;
+
+import org.dromara.sms4j.aliyun.config.AlibabaFactory;
+import org.dromara.sms4j.api.SmsBlend;
+import org.dromara.sms4j.api.universal.SupplierConfig;
+import org.dromara.sms4j.cloopen.config.CloopenFactory;
+import org.dromara.sms4j.ctyun.config.CtyunFactory;
+import org.dromara.sms4j.emay.config.EmayFactory;
+import org.dromara.sms4j.huawei.config.HuaweiFactory;
+import org.dromara.sms4j.jdcloud.config.JdCloudFactory;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+import org.dromara.sms4j.tencent.config.TencentFactory;
+import org.dromara.sms4j.unisms.config.UniFactory;
+import org.dromara.sms4j.yunpian.config.YunPianFactory;
+
+/**
+ * SupplierType
+ * 短信供应商枚举
+ * @author :Wind
+ * 2023/4/7 20:55
+ **/
+public enum SupplierType {
+ /** 阿里云*/
+ ALIBABA("阿里云短信", AlibabaFactory.instance()),
+ /** 华为云*/
+ HUAWEI("华为云短信", HuaweiFactory.instance()),
+ /** 云片*/
+ YUNPIAN("云片短信", YunPianFactory.instance()),
+ /** 腾讯云*/
+ TENCENT("腾讯云短信", TencentFactory.instance()),
+ /** 合一短信*/
+ UNI_SMS("合一短信", UniFactory.instance()),
+ /** 京东云 */
+ JD_CLOUD("京东云短信", JdCloudFactory.instance()),
+ /** 容联云 */
+ CLOOPEN("容联云短信", CloopenFactory.instance()),
+ /** 亿美软通*/
+ EMAY("亿美软通", EmayFactory.instance()),
+ /** 天翼云 */
+ CTYUN("天翼云短信", CtyunFactory.instance()),
+ ;
+
+
+ /**
+ * 渠道名称
+ */
+ private final String name;
+ /**
+ * 短信对象配置
+ */
+ private final BaseProviderFactory extends SmsBlend, ? extends SupplierConfig> providerFactory;
+
+
+ SupplierType(String name, BaseProviderFactory extends SmsBlend, ? extends SupplierConfig> providerFactory) {
+ this.name = name;
+ this.providerFactory = providerFactory;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public BaseProviderFactory extends SmsBlend, ? extends SupplierConfig> getProviderFactory() {
+ return providerFactory;
+ }
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentConfig.java
index 7143ab75..0f1ccef5 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentConfig.java
@@ -5,13 +5,14 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
+import org.dromara.sms4j.api.universal.SupplierConfig;
import org.dromara.sms4j.comm.config.BaseConfig;
@Data
@SuperBuilder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
-public class TencentConfig extends BaseConfig {
+public class TencentConfig extends BaseConfig implements SupplierConfig {
/**
* 短信sdkAppId
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentFactory.java
new file mode 100644
index 00000000..0b9571fe
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentFactory.java
@@ -0,0 +1,81 @@
+package org.dromara.sms4j.tencent.config;
+
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+import org.dromara.sms4j.tencent.service.TencentSmsImpl;
+
+/**
+ * TencentSmsConfig
+ *
建造腾讯云短信
+ *
+ * @author :Wind
+ * 2023/4/8 16:05
+ **/
+public class TencentFactory implements BaseProviderFactory {
+
+ private static TencentSmsImpl tencentSms;
+
+ private static final TencentFactory INSTANCE = new TencentFactory();
+
+ private static final class ConfigHolder {
+ private static TencentConfig config = TencentConfig.builder().build();
+ }
+
+ private TencentFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static TencentFactory instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * 建造一个腾讯云的短信实现
+ */
+ @Override
+ public TencentSmsImpl createSms(TencentConfig tencentConfig) {
+ if (tencentSms == null) {
+ tencentSms = new TencentSmsImpl(
+ tencentConfig,
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime()
+ );
+ }
+ return tencentSms;
+ }
+
+ /**
+ * 刷新对象
+ */
+ @Override
+ public TencentSmsImpl refresh(TencentConfig tencentConfig) {
+ tencentSms = new TencentSmsImpl(
+ tencentConfig,
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime()
+ );
+ return tencentSms;
+ }
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public TencentConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(TencentConfig config) {
+ ConfigHolder.config = config;
+ }
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentSmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentSmsConfig.java
deleted file mode 100644
index dee0cc4f..00000000
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/config/TencentSmsConfig.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.dromara.sms4j.tencent.config;
-
-import org.dromara.sms4j.comm.factory.BeanFactory;
-import org.dromara.sms4j.tencent.service.TencentSmsImpl;
-
-/**
- * TencentSmsConfig
- * 建造腾讯云短信
- *
- * @author :Wind
- * 2023/4/8 16:05
- **/
-public class TencentSmsConfig {
- private TencentSmsConfig() {
- }
-
- private static TencentSmsImpl tencentSms;
-
- private static TencentSmsConfig tencentSmsConfig;
-
- /**
- * 建造一个腾讯云的短信实现
- */
- public static TencentSmsImpl createTencentSms(TencentConfig tencentConfig) {
- if (tencentSmsConfig == null) {
- tencentSmsConfig = new TencentSmsConfig();
- }
- if (tencentSms == null) {
- tencentSms = new TencentSmsImpl(
- tencentConfig,
- BeanFactory.getExecutor(),
- BeanFactory.getDelayedTime()
- );
- }
- return tencentSms;
- }
-
- /**
- * 刷新对象
- */
- public static TencentSmsImpl refresh(TencentConfig tencentConfig) {
- if (tencentSmsConfig == null) {
- tencentSmsConfig = new TencentSmsConfig();
- }
- tencentSms = new TencentSmsImpl(
- tencentConfig,
- BeanFactory.getExecutor(),
- BeanFactory.getDelayedTime()
- );
- return tencentSms;
- }
-}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java
index 3caeeafd..d986b1be 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java
@@ -1,39 +1,36 @@
package org.dromara.sms4j.tencent.service;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.dtflys.forest.config.ForestConfiguration;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.jdcloud.sdk.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.callback.CallBack;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.constant.Constant;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
import org.dromara.sms4j.comm.exception.SmsBlendException;
-import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.comm.utils.SmsUtil;
import org.dromara.sms4j.tencent.config.TencentConfig;
import org.dromara.sms4j.tencent.utils.TencentUtils;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.Executor;
+/**
+ * @author wind
+ */
@Slf4j
-public class TencentSmsImpl implements SmsBlend {
+public class TencentSmsImpl extends AbstractSmsBlend {
private TencentConfig tencentSmsConfig;
- private Executor pool;
-
- private DelayedTime delayed;
-
- private final ForestConfiguration http = BeanFactory.getForestConfiguration();
-
public TencentSmsImpl(TencentConfig tencentSmsConfig, Executor pool, DelayedTime delayed) {
+ super(pool, delayed);
this.tencentSmsConfig = tencentSmsConfig;
- this.pool = pool;
- this.delayed = delayed;
}
@Override
@@ -77,7 +74,7 @@ public class TencentSmsImpl implements SmsBlend {
list.add(entry.getValue());
}
String[] s = new String[list.size()];
- return getSmsResponse(arrayToString(phones), list.toArray(s), templateId);
+ return getSmsResponse(SmsUtil.listToArray(phones), list.toArray(s), templateId);
}
private SmsResponse getSmsResponse(String[] phones, String[] messages, String templateId) {
@@ -101,102 +98,31 @@ public class TencentSmsImpl implements SmsBlend {
.onSuccess(((data, req, res) -> {
JSONObject jsonBody = res.get(JSONObject.class);
JSONObject response = jsonBody.getJSONObject("Response");
- JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
- smsResponse.setBizId(sendStatusSet.getJSONObject(0).getString("SerialNo"));
- smsResponse.setMessage(sendStatusSet.getJSONObject(0).getString("Message"));
- smsResponse.setCode(sendStatusSet.getJSONObject(0).getString("Code"));
+ String error = response.getStr("Error");
+ if (StringUtils.isNotBlank(error)){
+ smsResponse.setErrorCode("500");
+ smsResponse.setErrMessage(error);
+ }else {
+ JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
+ smsResponse.setBizId(sendStatusSet.getJSONObject(0).getStr("SerialNo"));
+ smsResponse.setMessage(sendStatusSet.getJSONObject(0).getStr("Message"));
+ smsResponse.setCode(sendStatusSet.getJSONObject(0).getStr("Code"));
+ }
}))
.onError((ex, req, res) -> {
JSONObject jsonBody = res.get(JSONObject.class);
- JSONObject response = jsonBody.getJSONObject("Response");
- JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
- smsResponse.setErrMessage(sendStatusSet.getJSONObject(0).getString("Message"));
- smsResponse.setErrorCode(sendStatusSet.getJSONObject(0).getString("Code"));
+ if (jsonBody == null) {
+ smsResponse.setErrorCode("500");
+ smsResponse.setErrMessage("tencent send sms response is null.check param");
+ } else {
+ JSONObject response = jsonBody.getJSONObject("Response");
+ JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
+ smsResponse.setErrMessage(sendStatusSet.getJSONObject(0).getStr("Message"));
+ smsResponse.setErrorCode(sendStatusSet.getJSONObject(0).getStr("Code"));
+ }
})
.execute();
return smsResponse;
}
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message) {
- pool.execute(() -> {
- sendMessage(phone, message);
- });
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(() -> {
- sendMessage(phone, templateId, messages);
- });
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, templateId, messages);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, templateId, messages);
- }
- }, delayedTime);
- }
-
- private String[] arrayToString(List list) {
- String[] strs = new String[list.size()];
- List toStr = new ArrayList<>();
- for (String s : list) {
- toStr.add("+86" + s);
- }
- return toStr.toArray(strs);
- }
-}
+}
\ No newline at end of file
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/utils/TencentUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/utils/TencentUtils.java
index 9742a5e4..8abbdb04 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/utils/TencentUtils.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/utils/TencentUtils.java
@@ -58,16 +58,14 @@ public class TencentUtils {
*/
public static String generateSignature(TencentConfig tencentConfig, String templateId, String[] messages, String[] phones,
String timestamp) throws Exception {
- // ************* 步骤 1:拼接规范请求串 *************
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.parseLong(timestamp + "000")));
String canonicalUri = "/";
String canonicalQueryString = "";
- String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + tencentConfig.getRequestUrl() + "\n";
+ String canonicalHeaders = "content-type:application/json; charset=utf-8\nhost:" + tencentConfig.getRequestUrl() + "\n";
String signedHeaders = "content-type;host";
- HashMap params = new HashMap<>();
- // 实际调用需要更新参数,这里仅作为演示签名验证通过的例子
+ Map params = new HashMap<>();
params.put("PhoneNumberSet", phones);
params.put("SmsSdkAppId", tencentConfig.getSdkAppId());
params.put("SignName", tencentConfig.getSignature());
@@ -75,20 +73,15 @@ public class TencentUtils {
params.put("TemplateParamSet", messages);
String payload = JSON.toJSONString(params);
String hashedRequestPayload = sha256Hex(payload);
- String canonicalRequest = HTTP_REQUEST_METHOD + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
- + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
- // ************* 步骤 2:拼接待签名字符串 *************
- String credentialScope = date + "/" + tencentConfig.getService() + "/" + "tc3_request";
+ String canonicalRequest = HTTP_REQUEST_METHOD + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
+ String credentialScope = date + "/" + tencentConfig.getService() + "/tc3_request";
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
String stringToSign = ALGORITHM + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
- // ************* 步骤 3:计算签名 *************
byte[] secretDate = hmac256(("TC3" + tencentConfig.getAccessKeySecret()).getBytes(StandardCharsets.UTF_8), date);
byte[] secretService = hmac256(secretDate, tencentConfig.getService());
byte[] secretSigning = hmac256(secretService, "tc3_request");
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
- // ************* 步骤 4:拼接 Authorization *************
- return ALGORITHM + " " + "Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", "
- + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
+ return ALGORITHM + " Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", SignedHeaders=" + signedHeaders + ", Signature=" + signature;
}
/**
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniConfig.java
index 67ca0395..791296ce 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniConfig.java
@@ -5,13 +5,14 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
+import org.dromara.sms4j.api.universal.SupplierConfig;
import org.dromara.sms4j.comm.config.BaseConfig;
@Data
@SuperBuilder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
-public class UniConfig extends BaseConfig {
+public class UniConfig extends BaseConfig implements SupplierConfig {
/**
* 是否为简易模式
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniSmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniFactory.java
similarity index 53%
rename from sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniSmsConfig.java
rename to sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniFactory.java
index 977605e3..17f3f5f3 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniSmsConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/config/UniFactory.java
@@ -1,6 +1,7 @@
package org.dromara.sms4j.unisms.config;
import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
import org.dromara.sms4j.unisms.core.Uni;
import org.dromara.sms4j.unisms.service.UniSmsImpl;
@@ -10,14 +11,27 @@ import org.dromara.sms4j.unisms.service.UniSmsImpl;
* @author :Wind
* 2023/4/8 15:46
**/
-public class UniSmsConfig {
-
- private UniSmsConfig(){}
-
- private static UniSmsConfig uniSmsConfig;
+public class UniFactory implements BaseProviderFactory {
private static UniSmsImpl uniSmsImpl;
+ private static final UniFactory INSTANCE = new UniFactory();
+
+ private static final class ConfigHolder {
+ private static UniConfig config = UniConfig.builder().build();
+ }
+
+ private UniFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static UniFactory instance() {
+ return INSTANCE;
+ }
+
/** 短信配置*/
private void buildSms(UniConfig uniConfig){
@@ -33,12 +47,10 @@ public class UniSmsConfig {
* 建造一个短信实现对像
* @author :Wind
*/
- public static UniSmsImpl createUniSms(UniConfig uniConfig){
- if (uniSmsConfig == null){
- uniSmsConfig = new UniSmsConfig();
- }
+ @Override
+ public UniSmsImpl createSms(UniConfig uniConfig){
if (uniSmsImpl == null){
- uniSmsConfig.buildSms(uniConfig);
+ this.buildSms(uniConfig);
uniSmsImpl = new UniSmsImpl(
uniConfig,
BeanFactory.getExecutor(),
@@ -53,11 +65,9 @@ public class UniSmsConfig {
*
刷新对象
* @author :Wind
*/
- public static UniSmsImpl refresh(UniConfig uniConfig){
- if (uniSmsConfig == null){
- uniSmsConfig = new UniSmsConfig();
- }
- uniSmsConfig.buildSms(uniConfig);
+ @Override
+ public UniSmsImpl refresh(UniConfig uniConfig){
+ this.buildSms(uniConfig);
uniSmsImpl = new UniSmsImpl(
uniConfig,
BeanFactory.getExecutor(),
@@ -65,4 +75,23 @@ public class UniSmsConfig {
);
return uniSmsImpl;
}
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public UniConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(UniConfig config) {
+ ConfigHolder.config = config;
+ }
+
}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniClient.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniClient.java
index 7306ea7a..b4c1522f 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniClient.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniClient.java
@@ -1,6 +1,6 @@
package org.dromara.sms4j.unisms.core;
-import com.alibaba.fastjson.JSONObject;
+import cn.hutool.json.JSONUtil;
import com.dtflys.forest.config.ForestConfiguration;
import org.dromara.sms4j.comm.exception.SmsBlendException;
import org.dromara.sms4j.comm.factory.BeanFactory;
@@ -79,6 +79,7 @@ public class UniClient {
/**
* request
*
向 uni-sms发送请求
+ *
* @param action 接口名称
* @author :Wind
*/
@@ -91,21 +92,19 @@ public class UniClient {
headers.put("User-Agent", USER_AGENT);
headers.put("Content-Type", "application/json;charset=utf-8");
headers.put("Accept", "application/json");
- return new UniResponse(
- JSONObject.parseObject(
- http.post(this.endpoint)
- .addHeader(headers)
- .addQuery(this.sign(query))
- .addBody(JSONObject.toJSONString(data))
- .successWhen(((req, res) -> {
- return res.noException() && // 请求过程没有异常
- res.statusIsNot(500); // 不能是 500
- }))
- .onError((ex, req, res) -> {
- throw new SmsBlendException(ex.getMessage());
- })
- .executeAsString()
- ));
+ String str = http.post(this.endpoint)
+ .addHeader(headers)
+ .addQuery(this.sign(query))
+ .addBody(JSONUtil.toJsonStr(data))
+ .successWhen(((req, res) -> {
+ return res.noException() && // 请求过程没有异常
+ res.statusIsNot(500); // 不能是 500
+ }))
+ .onError((ex, req, res) -> {
+ throw new SmsBlendException(ex.getMessage());
+ })
+ .executeAsString();
+ return new UniResponse(JSONUtil.parseObj(str));
}
public static class Builder {
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java
index 6ea1bba8..fd80e3b5 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java
@@ -1,8 +1,10 @@
package org.dromara.sms4j.unisms.core;
-import com.alibaba.fastjson.JSONObject;
+import cn.hutool.json.JSONObject;
import org.dromara.sms4j.comm.exception.SmsBlendException;
+import java.util.Objects;
+
public class UniResponse {
public static final String REQUEST_ID_HEADER_KEY = "x-uni-request-id";
@@ -20,22 +22,23 @@ public class UniResponse {
*/
public UniResponse(final JSONObject response) throws SmsBlendException {
JSONObject body = response.getJSONObject("data");
- this.status = body.getJSONArray("messages").getJSONObject(0).getString("status");
- this.requestId = body.getJSONArray("messages").getJSONObject(0).getString("id");
- this.raw = body;
-
- if (this.status != "400") {
- String code = response.getString("code");
- String message = body.getJSONArray("messages").getString(0);
- if (!"0".equals(code)) {
- throw new SmsBlendException(message, code, this.requestId);
- }
- this.code = code;
- this.message = message;
+ if (!Objects.isNull(body)) {
+ this.status = body.getJSONArray("messages").getJSONObject(0).getStr("status");
+ this.requestId = body.getJSONArray("messages").getJSONObject(0).getStr("id");
+ this.raw = body;
this.data = body;
}
- else {
- throw new SmsBlendException(response.getString("message"), "-1");
+ if (this.status != "400") {
+ String code = response.getStr("code");
+ if (!"0".equals(code)) {
+ this.message = response.getStr("message");
+ } else {
+ this.message = body.getJSONArray("messages").getStr(0);
+ ;
+ }
+ this.code = code;
+ } else {
+ throw new SmsBlendException(response.getStr("message"), "-1");
}
}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java
index b17f4b2e..bf562b93 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java
@@ -1,13 +1,12 @@
package org.dromara.sms4j.unisms.service;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.callback.CallBack;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
import org.dromara.sms4j.comm.exception.SmsBlendException;
import org.dromara.sms4j.unisms.config.UniConfig;
-import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.unisms.core.Uni;
import org.dromara.sms4j.unisms.core.UniResponse;
@@ -16,11 +15,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.TimerTask;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
-import java.util.function.Supplier;
/**
@@ -31,16 +26,13 @@ import java.util.function.Supplier;
**/
@Slf4j
-public class UniSmsImpl implements SmsBlend {
+public class UniSmsImpl extends AbstractSmsBlend {
private UniConfig config;
- private Executor pool;
- private DelayedTime delayed;
public UniSmsImpl(UniConfig config, Executor pool, DelayedTime delayed) {
+ super(pool,delayed);
this.config = config;
- this.pool = pool;
- this.delayed = delayed;
}
@Override
@@ -90,76 +82,6 @@ public class UniSmsImpl implements SmsBlend {
return getSmsResponse(data);
}
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- public void sendMessageAsync(String phone, String message) {
- pool.execute(()->{
- sendMessage(phone, message);
- });
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(()->{
- sendMessage(phone,templateId,messages);
- });
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone,message);
- }
- },delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone,templateId,messages);
- }
- },delayedTime);
- }
-
- @Override
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones,message);
- }
- },delayedTime);
- }
-
- @Override
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones,templateId,messages);
- }
- },delayedTime);
- }
-
private SmsResponse getSmsResponse( Map data) {
SmsResponse smsResponse = new SmsResponse();
try {
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunPianFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunPianFactory.java
new file mode 100644
index 00000000..975994f0
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunPianFactory.java
@@ -0,0 +1,72 @@
+package org.dromara.sms4j.yunpian.config;
+
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.provider.base.BaseProviderFactory;
+import org.dromara.sms4j.yunpian.service.YunPianSmsImpl;
+
+public class YunPianFactory implements BaseProviderFactory {
+
+ private static YunPianSmsImpl yunpianSmsImpl;
+
+ private static final YunPianFactory INSTANCE = new YunPianFactory();
+
+ private static final class ConfigHolder {
+ private static YunpianConfig config = YunpianConfig.builder().build();
+ }
+
+ private YunPianFactory() {
+ }
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static YunPianFactory instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * 建造一个云片短信实现
+ */
+ @Override
+ public YunPianSmsImpl createSms(YunpianConfig yunpianConfig){
+ if (yunpianSmsImpl == null){
+ yunpianSmsImpl = new YunPianSmsImpl(
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime(),
+ yunpianConfig
+ );
+ }
+ return yunpianSmsImpl;
+ }
+
+ /** 刷新对象*/
+ @Override
+ public YunPianSmsImpl refresh(YunpianConfig yunpianConfig){
+ yunpianSmsImpl = new YunPianSmsImpl(
+ BeanFactory.getExecutor(),
+ BeanFactory.getDelayedTime(),
+ yunpianConfig
+ );
+ return yunpianSmsImpl;
+ }
+
+ /**
+ * 获取配置
+ * @return 配置对象
+ */
+ @Override
+ public YunpianConfig getConfig() {
+ return ConfigHolder.config;
+ }
+
+ /**
+ * 设置配置
+ * @param config 配置对象
+ */
+ @Override
+ public void setConfig(YunpianConfig config) {
+ ConfigHolder.config = config;
+ }
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunPianSmsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunPianSmsConfig.java
deleted file mode 100644
index 0d9973ee..00000000
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunPianSmsConfig.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.dromara.sms4j.yunpian.config;
-
-import com.dtflys.forest.Forest;
-import com.dtflys.forest.config.ForestConfiguration;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.yunpian.service.YunPianSmsImpl;
-
-public class YunPianSmsConfig {
-
-
- public YunpianConfig yunpianConfig(){
- return YunpianConfig.builder().build();
- }
-
-
- public ForestConfiguration forestConfiguration(YunpianConfig yunpianConfig) {
- return Forest.config().setBackendName("httpclient");
- }
-
-
- public SmsBlend smsBlend() {
- return new YunPianSmsImpl();
- }
-}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunpianConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunpianConfig.java
index d08dd964..a09ae1dc 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunpianConfig.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/config/YunpianConfig.java
@@ -1,26 +1,22 @@
package org.dromara.sms4j.yunpian.config;
-import lombok.Builder;
import lombok.Data;
-
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import lombok.experimental.SuperBuilder;
+import org.dromara.sms4j.api.universal.SupplierConfig;
+import org.dromara.sms4j.comm.config.BaseConfig;
@Data
-@Builder
-public class YunpianConfig {
- /**
- * 账号唯一标识
- */
- private String apikey;
+@SuperBuilder
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class YunpianConfig extends BaseConfig implements SupplierConfig {
/**
* 短信发送后将向这个地址推送(运营商返回的)发送报告
*/
private String callbackUrl;
- /**
- * 模板Id
- */
- private String templateId;
-
/**
* 模板变量名称
*/
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java
index 77aba422..1b6536a6 100644
--- a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java
@@ -1,40 +1,46 @@
package org.dromara.sms4j.yunpian.service;
-import com.alibaba.fastjson.JSONObject;
-import com.dtflys.forest.config.ForestConfiguration;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.callback.CallBack;
+import cn.hutool.json.JSONObject;
+import org.dromara.sms4j.api.AbstractSmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.comm.constant.Constant;
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.comm.utils.SmsUtil;
import org.dromara.sms4j.yunpian.config.YunpianConfig;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
-import static org.dromara.sms4j.comm.utils.SmsUtil.listToString;
+/**
+ * @author wind
+ */
+public class YunPianSmsImpl extends AbstractSmsBlend {
-public class YunPianSmsImpl implements SmsBlend {
-
- private Executor pool;
-
- private DelayedTime delayed;
+ public YunPianSmsImpl(Executor pool, DelayedTime delayed, YunpianConfig config) {
+ super(pool, delayed);
+ this.config = config;
+ }
private YunpianConfig config;
- private ForestConfiguration http;
-
private static SmsResponse getSmsResponse(JSONObject execute) {
SmsResponse smsResponse = new SmsResponse();
- smsResponse.setCode(execute.getString("code"));
- smsResponse.setMessage(execute.getString("msg"));
- smsResponse.setBizId(execute.getString("sid"));
- if (execute.getInteger("code") != 0) {
- smsResponse.setErrMessage(execute.getString("msg"));
+ if (execute == null) {
+ smsResponse.setErrorCode("500");
+ smsResponse.setErrMessage("yunpian send sms response is null.check param");
+ return smsResponse;
+ }
+ smsResponse.setCode(execute.getStr("code"));
+ smsResponse.setMessage(execute.getStr("msg"));
+ smsResponse.setBizId(execute.getStr("sid"));
+ if (execute.getInt("code") != 0) {
+ smsResponse.setErrMessage(execute.getStr("msg"));
}
smsResponse.setData(execute);
return smsResponse;
@@ -50,7 +56,7 @@ public class YunPianSmsImpl implements SmsBlend {
@Override
@Restricted
public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) {
- Map body = setBody(phone, "", messages,templateId);
+ Map body = setBody(phone, "", messages, templateId);
return getSendResponse(body);
}
@@ -60,7 +66,7 @@ public class YunPianSmsImpl implements SmsBlend {
if (phones.size() > 1000) {
throw new SmsBlendException("单次发送超过最大发送上限,建议每次群发短信人数低于1000");
}
- return sendMessage(listToString(phones), message);
+ return sendMessage(SmsUtil.listToString(phones), message);
}
@Override
@@ -69,79 +75,7 @@ public class YunPianSmsImpl implements SmsBlend {
if (phones.size() > 1000) {
throw new SmsBlendException("单次发送超过最大发送上限,建议每次群发短信人数低于1000");
}
- return sendMessage(listToString(phones), templateId, messages);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String message) {
- pool.execute(() -> sendMessage(phone, message));
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) {
- CompletableFuture smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
- smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
- }
-
- @Override
- @Restricted
- public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) {
- pool.execute(() -> {
- sendMessage(phone, templateId, messages);
- });
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- sendMessage(phone, templateId, messages);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String message, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, message);
- }
- }, delayedTime);
- }
-
- @Override
- @Restricted
- public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) {
- this.delayed.schedule(new TimerTask() {
- @Override
- public void run() {
- massTexting(phones, templateId, messages);
- }
- }, delayedTime);
+ return sendMessage(SmsUtil.listToString(phones), templateId, messages);
}
private String formattingMap(Map messages) {
@@ -165,11 +99,12 @@ public class YunPianSmsImpl implements SmsBlend {
message.put(config.getTemplateName(), mes);
}
Map body = new HashMap<>();
- body.put("apikey", config.getApikey());
+ body.put("apikey", config.getAccessKeyId());
body.put("mobile", phone);
body.put("tpl_id", tplId);
body.put("tpl_value", formattingMap(message));
- if (!config.getCallbackUrl().isEmpty()) body.put("callback_url", config.getCallbackUrl());
+ if (config.getCallbackUrl() != null && !config.getCallbackUrl().isEmpty())
+ body.put("callback_url", config.getCallbackUrl());
return body;
}
@@ -182,7 +117,7 @@ public class YunPianSmsImpl implements SmsBlend {
private SmsResponse getSendResponse(Map body) {
Map headers = getHeaders();
- AtomicReference smsResponse = null;
+ AtomicReference smsResponse = new AtomicReference<>();
http.post(Constant.YUNPIAN_URL + "/sms/tpl_single_send.json")
.addHeader(headers)
.addBody(body)
diff --git a/sms4j-solon-plugin/pom.xml b/sms4j-solon-plugin/pom.xml
new file mode 100644
index 00000000..75dc6f32
--- /dev/null
+++ b/sms4j-solon-plugin/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+ org.dromara.sms4j
+ sms4j
+ ${revision}
+ ../pom.xml
+
+
+ sms4j-solon-plugin
+
+ sms4j-solon-plugin
+ sms4j-solon-plugin
+
+
+
+
+ org.noear
+ solon
+ ${solon.version}
+
+
+
+ org.dromara.sms4j
+ sms4j-core
+
+
+
+ org.redisson
+ redisson
+ ${redisson.version}
+
+
+
+ org.noear
+ solon-test
+ ${solon.version}
+ test
+
+
+
diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/XPluginImpl.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/XPluginImpl.java
new file mode 100644
index 00000000..d30071fc
--- /dev/null
+++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/XPluginImpl.java
@@ -0,0 +1,16 @@
+package org.dromara.sms4j.solon;
+
+import org.dromara.sms4j.solon.config.SmsAutowiredConfig;
+import org.noear.solon.core.AopContext;
+import org.noear.solon.core.Plugin;
+
+/**
+ * @author noear 2023/5/16 created
+ */
+public class XPluginImpl implements Plugin {
+ @Override
+ public void start(AopContext context) throws Throwable {
+ context.beanMake(SmsAutowiredConfig.class);
+ SmsAutowiredConfig.aopContext = context;
+ }
+}
diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/aop/SolonRestrictedProcess.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/aop/SolonRestrictedProcess.java
new file mode 100644
index 00000000..360051a3
--- /dev/null
+++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/aop/SolonRestrictedProcess.java
@@ -0,0 +1,55 @@
+package org.dromara.sms4j.solon.aop;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.smsProxy.RestrictedProcess;
+import org.dromara.sms4j.comm.config.SmsConfig;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.comm.utils.SmsUtil;
+import org.dromara.sms4j.solon.utils.RedisUtils;
+import org.noear.solon.core.AopContext;
+
+@Slf4j
+public class SolonRestrictedProcess extends RestrictedProcess {
+
+ private RedisUtils redis;
+ private static final Long minTimer = 60 * 1000L;
+ private static final Long accTimer = 24 * 60 * 60 * 1000L;
+ private static final String REDIS_KEY = "sms:restricted:";
+
+ public SolonRestrictedProcess(AopContext context){
+ context.getBeanAsync(RedisUtils.class, bean->{
+ redis = bean;
+ });
+ }
+
+ @Override
+ public SmsBlendException process(SmsConfig config, String args) throws Exception {
+ Integer accountMax = config.getAccountMax();//每日最大发送量
+ Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
+ if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
+ Integer i = (Integer) redis.getByKey(REDIS_KEY+args + "max");
+ if (SmsUtil.isEmpty(i)) {
+ redis.setOrTime(REDIS_KEY+args + "max", 1,accTimer/1000);
+ } else if (i > accountMax) {
+ log.info("The phone:"+args +",number of short messages reached the maximum today");
+ return new SmsBlendException("The phone:"+args +",number of short messages reached the maximum today");
+ } else {
+ redis.setOrTime(REDIS_KEY+args + "max", i + 1,accTimer/1000);
+ }
+ }
+ if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
+ Integer o = (Integer) redis.getByKey(REDIS_KEY+args);
+ if (SmsUtil.isNotEmpty(o)) {
+ if (o < minuteMax) {
+ redis.setOrTime(REDIS_KEY+args, o + 1,minTimer/1000);
+ } else {
+ log.info("The phone:"+args +",number of short messages reached the maximum today");
+ return new SmsBlendException("The phone:", args + " Text messages are sent too often!");
+ }
+ } else {
+ redis.setOrTime(REDIS_KEY+args, 1,minTimer/1000);
+ }
+ }
+ return null;
+ }
+}
diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsAutowiredConfig.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsAutowiredConfig.java
new file mode 100644
index 00000000..bbb282a8
--- /dev/null
+++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsAutowiredConfig.java
@@ -0,0 +1,93 @@
+package org.dromara.sms4j.solon.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.smsProxy.SmsInvocationHandler;
+import org.dromara.sms4j.comm.config.SmsBanner;
+import org.dromara.sms4j.comm.config.SmsConfig;
+import org.dromara.sms4j.comm.config.SmsSqlConfig;
+import org.dromara.sms4j.comm.constant.Constant;
+import org.dromara.sms4j.comm.delayedTime.DelayedTime;
+import org.dromara.sms4j.comm.factory.BeanFactory;
+import org.dromara.sms4j.core.SupplierSqlConfig;
+import org.dromara.sms4j.solon.aop.SolonRestrictedProcess;
+import org.dromara.sms4j.solon.utils.RedisUtils;
+import org.noear.solon.Solon;
+import org.noear.solon.Utils;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Condition;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.annotation.Inject;
+import org.noear.solon.core.AopContext;
+import org.noear.solon.core.Props;
+
+import java.util.concurrent.Executor;
+
+
+@Slf4j
+@Configuration
+public class SmsAutowiredConfig {
+
+ public static AopContext aopContext;
+
+ private T injectObj(String prefix, T obj) {
+ //@Inject 只支持在字段、参数、类型上注入
+ Props props = Solon.cfg().getProp(prefix);
+ Utils.injectProperties(obj, props);
+ return obj;
+ }
+
+ @Bean
+ public SmsSqlConfig smsSqlConfig() {
+ return injectObj("sms.sql", BeanFactory.getSmsSqlConfig());
+ }
+
+ @Bean
+ public SmsConfig smsConfig(){
+ SmsConfig smsConfig = injectObj("sms", BeanFactory.getSmsConfig());
+
+ smsConfigCheck();
+
+ return smsConfig;
+ }
+
+ /** 注入一个定时器*/
+ @Bean
+ public DelayedTime delayedTime(){
+ return BeanFactory.getDelayedTime();
+ }
+
+ /** 注入线程池*/
+ @Bean("smsExecutor")
+ public Executor taskExecutor(@Inject SmsConfig config){
+ return BeanFactory.setExecutor(config);
+ }
+
+
+ /** smsConfig参数意义为确保注入时smsConfig已经存在*/
+ @Bean
+ @Condition(onProperty ="${sms.config-type}=config_file")
+ public SupplierConfig supplierConfig(@Inject SmsConfig smsConfig){
+ return new SupplierConfig();
+ }
+
+ @Bean
+ @Condition(onProperty ="${sms.config-type}=sql_config")
+ public SupplierSqlConfig supplierSqlConfig(@Inject SmsSqlConfig smsSqlConfig){
+ return new SupplierSqlConfig();
+ }
+
+
+ private void smsConfigCheck(){
+ /* 如果配置中启用了redis,则注入redis工具*/
+ if (BeanFactory.getSmsConfig().getRedisCache()){
+ Solon.context().wrapAndPut(RedisUtils.class);
+ SmsInvocationHandler.setRestrictedProcess(new SolonRestrictedProcess(aopContext));
+ log.debug("The redis cache is enabled for sms4j");
+ }
+
+ //打印banner
+ if (BeanFactory.getSmsConfig().getIsPrint()){
+ SmsBanner.PrintBanner(Constant.VERSION);
+ }
+ }
+}
diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfig.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfig.java
new file mode 100644
index 00000000..39ea927e
--- /dev/null
+++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfig.java
@@ -0,0 +1,84 @@
+package org.dromara.sms4j.solon.config;
+
+import org.dromara.sms4j.aliyun.config.AlibabaConfig;
+import org.dromara.sms4j.cloopen.config.CloopenConfig;
+import org.dromara.sms4j.core.config.SupplierFactory;
+import org.dromara.sms4j.ctyun.config.CtyunConfig;
+import org.dromara.sms4j.emay.config.EmayConfig;
+import org.dromara.sms4j.huawei.config.HuaweiConfig;
+import org.dromara.sms4j.jdcloud.config.JdCloudConfig;
+import org.dromara.sms4j.tencent.config.TencentConfig;
+import org.dromara.sms4j.unisms.config.UniConfig;
+import org.dromara.sms4j.yunpian.config.YunpianConfig;
+import org.noear.solon.Solon;
+import org.noear.solon.Utils;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.core.Props;
+
+@Configuration
+public class SupplierConfig {
+ private T injectObj(String prefix, T obj) {
+ //@Inject 只支持在字段、参数、类型上注入
+ Props props = Solon.cfg().getProp(prefix);
+ Utils.injectProperties(obj, props);
+ return obj;
+ }
+
+
+ /** 阿里差异化配置*/
+ @Bean
+ public AlibabaConfig alibabaConfig(){
+ return injectObj("sms.alibaba", SupplierFactory.getAlibabaConfig());
+ }
+
+ /** 华为差异化配置*/
+ @Bean
+ public HuaweiConfig huaweiConfig(){
+ return injectObj("sms.huawei", SupplierFactory.getHuaweiConfig());
+ }
+
+ /** 云片短信差异化配置*/
+ @Bean
+ public YunpianConfig yunpianConfig(){
+ return injectObj("sms.yunpian", SupplierFactory.getYunpianConfig());
+ }
+
+ /** 合一短信差异化配置*/
+ @Bean
+ public UniConfig uniConfig(){
+ return injectObj("sms.uni", SupplierFactory.getUniConfig());
+ }
+
+ /** 腾讯短信差异化配置*/
+ @Bean
+ public TencentConfig tencentConfig(){
+ return injectObj("sms.tencent", SupplierFactory.getTencentConfig());
+ }
+
+ /** 京东云短信差异化配置 */
+ @Bean
+ public JdCloudConfig jdCloudConfig(){
+ return injectObj("sms.jdcloud", SupplierFactory.getJdCloudConfig());
+ }
+
+ /** 容联云短信差异化配置 */
+ @Bean
+ public CloopenConfig cloopenConfig(){
+ return injectObj("sms.cloopen", SupplierFactory.getCloopenConfig());
+ }
+
+ /**
+ * 亿美软通短信差异化配置
+ */
+ @Bean
+ public EmayConfig emayConfig(){
+ return injectObj("sms.emay", SupplierFactory.getEmayConfig());
+ }
+
+ /** 天翼云短信差异化配置 */
+ @Bean
+ public CtyunConfig ctyunConfig(){
+ return injectObj("sms.ctyun", SupplierFactory.getCtyunConfig());
+ }
+}
diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/utils/RedisUtils.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/utils/RedisUtils.java
new file mode 100644
index 00000000..fd9e42c5
--- /dev/null
+++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/utils/RedisUtils.java
@@ -0,0 +1,468 @@
+package org.dromara.sms4j.solon.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.noear.solon.Solon;
+import org.redisson.api.RedissonClient;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+
+@Slf4j
+public class RedisUtils {
+
+ private RedissonClient redisTemplate;
+
+ public RedisUtils() {
+ Thread t = new Thread(()->{
+ //如果获取到的bean为null则等待后重试,最多重试五次
+ for(int i = 0; i < 5 ;i++){
+ RedissonClient bean = Solon.context().getBean(RedissonClient.class);
+ if (Objects.isNull(bean)){
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }else{
+ redisTemplate = bean;
+ return;
+ }
+ }
+ });
+ t.start();
+ }
+
+ public RedisUtils(RedissonClient redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }
+
+ /**
+ * 说明:设置redis的key的到期时间
+ *
+ * @param key redis的key
+ * @param time 到期时间
+ * @name: setTimeByKey
+ * @author :Wind
+ */
+ public boolean setTimeByKey(String key, Long time) {
+ try {
+ if (time > 0) {
+ redisTemplate.getBucket(key).expire(time, TimeUnit.SECONDS);
+ return true;
+ }
+ return false;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * 说明:放入redis
+ *
+ * @param key 要放入的key
+ * @param value 要放入的value
+ * @name: set
+ * @author :Wind
+ */
+ public boolean set(String key, Object value) {
+ redisTemplate.getBucket(key).set(value);
+ return true;
+ }
+
+ /**
+ * 说明:放入带过期时间的缓存
+ *
+ * @param time 到期时间(秒)
+ * @name: setOrTime
+ * @author :Wind
+ */
+ public boolean setOrTime(String key, Object value, Long time) {
+ try {
+ redisTemplate.getBucket(key).set(value, time, TimeUnit.SECONDS);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * 说明:将Map中的数据批量放置到redis中
+ *
+ *
+ * @param valueMap 要放入的数据
+ * @name: multiSet
+ * @author :Wind
+ */
+ public boolean multiSet(Map valueMap) {
+ try {
+ valueMap.forEach((key, val) -> {
+ redisTemplate.getBucket((String) key).set(val);
+ });
+ return true;
+ } catch (Exception e) {
+ log.error(e.toString());
+ return false;
+ }
+ }
+
+ /**
+ * 说明:获取key对应的值
+ *
+ * @param key 要查询的key
+ * @name: getByKey
+ * @author :Wind
+ */
+ public Object getByKey(String key) {
+ return redisTemplate.getBucket(key).get();
+ }
+
+ /**
+ *
说明:获取字符串型值
+ *
+ * @param
+ * @name: getKyeString
+ * @author :Wind
+ */
+ public String getKyeString(String key) {
+ return (String) getByKey(key);
+ }
+
+ /**
+ * 说明:判断key是否存在
+ *
+ * @param key 要判断的key
+ * @name: hasKey
+ * @author :Wind
+ */
+ public Boolean hasKey(String key) {
+ return redisTemplate.getBucket(key).isExists();
+ }
+
+// /**
+// * 说明:根据key删除redis缓存可以批量删除
+// *
+// * @param key 要删除的key
+// * @name: deleteKey
+// * @author :Wind
+// */
+// public Boolean deleteKey(String... key) {
+// if (key != null && key.length > 0) {
+// if (key.length == 1) {
+// return redisTemplate.getBucket(key[0]).delete();
+// } else {
+// Long delete = redisTemplate.(Arrays.asList(key));
+// return delete >= 1L;
+// }
+// }
+// return false;
+// }
+//
+// public Boolean delete(String key) {
+// Set keys = redisTemplate.keys(key + "*");
+// redisTemplate.removeByKeys(keys);
+// return true;
+// }
+
+// /**
+// * 根据key 获取key的过期时间
+// *
+// * @param key 键 不能为null
+// * @return 时间(秒) 返回-1, 代表为永久有效
+// */
+// public Long getKeyExpire(String key) {
+// return redisTemplate.ttl(key);
+// }
+//
+// /**
+// * 修改redis中key的名称
+// *
+// * @param oldKey 旧的key值
+// * @param newKey 新的key值
+// */
+// public void renameKey(String oldKey, String newKey) {
+// redisTemplate..ren(oldKey, newKey);
+// }
+//
+// /**
+// * 说明:将map对象存入redis
+// *
+// *
+// * @param map 要存入redis中的map
+// * @name: setMap
+// * @author :Wind
+// */
+// public void MapSetMap(String key, Map map) {
+// redisClient.getHash(key).putAll(map);
+// }
+//
+// /**
+// * 说明:获取所有hash表中字段
+// *
+// *
+// * @param
+// * @name: getMapByKey
+// * @author :Wind
+// */
+// public Set