diff --git a/sms4j-api/pom.xml b/sms4j-api/pom.xml index 5b400c67..f70d9ef7 100644 --- a/sms4j-api/pom.xml +++ b/sms4j-api/pom.xml @@ -19,10 +19,5 @@ org.dromara.sms4j sms4j-comm - - - cn.hutool - hutool-http - diff --git a/sms4j-comm/pom.xml b/sms4j-comm/pom.xml index f2af7138..c330b7ea 100644 --- a/sms4j-comm/pom.xml +++ b/sms4j-comm/pom.xml @@ -25,5 +25,11 @@ cn.hutool hutool-json + + + cn.hutool + hutool-http + + 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 3eb52eb2..0b78a827 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 @@ -28,6 +28,8 @@ public abstract class Constant { */ public static final String FROM_URLENCODED = "application/x-www-form-urlencoded"; + public static final String ACCEPT = "application/json"; + public static final String APPLICATION_JSON_UTF8 = "application/json; charset=utf-8"; /** diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsHttpUtil.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsHttpUtil.java new file mode 100644 index 00000000..e2a68da1 --- /dev/null +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsHttpUtil.java @@ -0,0 +1,79 @@ +package org.dromara.sms4j.comm.utils; + +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import org.dromara.sms4j.comm.exception.SmsBlendException; + +import java.util.Map; + +public class SmsHttpUtil { + + private SmsHttpUtil() { + } + + private static class SmsHttpHolder { + private static final SmsHttpUtil INSTANCE = new SmsHttpUtil(); + } + + public static SmsHttpUtil instance() { + return SmsHttpHolder.INSTANCE; + } + + /** + * 发送post json请求 + * @param url 请求地址 + * @param headers 请求头 + * @param body 请求体(json格式字符串) + * @return 返回体 + */ + public JSONObject postJson(String url, Map headers, String body){ + try(HttpResponse response = HttpRequest.post(url) + .addHeaders(headers) + .body(body) + .execute()){ + return JSONUtil.parseObj(response.body()); + }catch (Exception e){ + throw new SmsBlendException(e.getMessage()); + } + } + + /** + * 发送post json请求 + * @param url 请求地址 + * @param headers 请求头 + * @param body 请求体(map格式请求体) + * @return 返回体 + */ + public JSONObject postJson(String url, Map headers, Map body){ + return postJson(url, headers, JSONUtil.toJsonStr(body)); + } + + /** + * 发送post form 请求 + * @param url 请求地址 + * @param headers 请求头 + * @param body 请求体(map格式请求体) + * @return 返回体 + */ + public JSONObject postFrom(String url, Map headers, Map body){ + try(HttpResponse response = HttpRequest.post(url) + .addHeaders(headers) + .form(body) + .execute()){ + return JSONUtil.parseObj(response.body()); + }catch (Exception e){ + throw new SmsBlendException(e.getMessage()); + } + } + + /** + * 线程睡眠 + * @param retryInterval 秒 + */ + public void safeSleep(int retryInterval){ + ThreadUtil.safeSleep(retryInterval * 1000L); + } +} 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 98cbf371..1896a8b6 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,13 +1,12 @@ package org.dromara.sms4j.aliyun.service; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; 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.entity.SmsResponse; +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; @@ -15,6 +14,7 @@ import org.dromara.sms4j.provider.service.AbstractSmsBlend; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Executor; /** @@ -28,6 +28,7 @@ import java.util.concurrent.Executor; public class AlibabaSmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "alibaba"; + private int retry = 0; /** * AlibabaSmsImpl @@ -89,15 +90,27 @@ public class AlibabaSmsImpl extends AbstractSmsBlend { throw new SmsBlendException(e.getMessage()); } log.debug("requestUrl {}", requestUrl); - try(HttpResponse response = HttpRequest.post(requestUrl) - .header("Content-Type", "application/x-www-form-urlencoded") - .body(paramStr) - .execute()){ - JSONObject body = JSONUtil.parseObj(response.body()); - return this.getResponse(body); + try { + Map headers = new LinkedHashMap<>(1); + headers.put("Content-Type", Constant.FROM_URLENCODED); + SmsResponse smsResponse = getResponse(http.postJson(requestUrl, headers, paramStr)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phone, message, templateId); + }catch (SmsBlendException e){ + return requestRetry(phone, message, templateId); } } + private SmsResponse requestRetry(String phone, String message, String templateId) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return getSmsResponse(phone, message, templateId); + } + private SmsResponse getResponse(JSONObject resJson) { SmsResponse smsResponse = new SmsResponse(); smsResponse.setSuccess("OK".equals(resJson.getStr("Code"))); 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 578c5b37..40dbec4a 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 @@ -1,6 +1,5 @@ package org.dromara.sms4j.cloopen.service; -import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.IdUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; @@ -51,15 +50,15 @@ public class CloopenSmsImpl extends AbstractSmsBlend { @Override public SmsResponse massTexting(List phones, String message) { - LinkedHashMap map = new LinkedHashMap<>(); + LinkedHashMap map = new LinkedHashMap<>(1); map.put(IdUtil.fastSimpleUUID(), message); return massTexting(phones, getConfig().getTemplateId(), map); } @Override public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { - CloopenHelper helper = new CloopenHelper(getConfig()); - Map paramMap = MapUtil.newHashMap(4); + CloopenHelper helper = new CloopenHelper(getConfig(), http); + Map paramMap = new LinkedHashMap<>(4); paramMap.put("to", String.join(",", phones)); paramMap.put("appId", getConfig().getAppId()); paramMap.put("templateId", templateId); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java index d670038e..04f6b57e 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java @@ -4,14 +4,16 @@ import cn.hutool.core.codec.Base64; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.crypto.SecureUtil; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.cloopen.config.CloopenConfig; +import org.dromara.sms4j.comm.constant.Constant; +import org.dromara.sms4j.comm.exception.SmsBlendException; +import org.dromara.sms4j.comm.utils.SmsHttpUtil; import java.util.Date; +import java.util.LinkedHashMap; import java.util.Map; /** @@ -20,33 +22,48 @@ import java.util.Map; * @author Charles7c * @since 2023/4/17 20:57 */ +@Slf4j public class CloopenHelper { private final CloopenConfig config; + private final SmsHttpUtil http; + private int retry = 0; - public CloopenHelper(CloopenConfig config) { + public CloopenHelper(CloopenConfig config, SmsHttpUtil http) { this.config = config; + this.http = http; } public SmsResponse smsResponse(Map paramMap){ - String timestamp = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN); + try { + String timestamp = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN); - String url = String.format("%s/Accounts/%s/SMS/TemplateSMS?sig=%s", - config.getBaseUrl(), - config.getAccessKeyId(), - this.generateSign(config.getAccessKeyId(), config.getAccessKeySecret(), timestamp)); - - try(HttpResponse response = HttpRequest.post(url) - .header("Accept", "application/json") - .header("Content-Type", "application/json;charset=utf-8") - .header("Authorization", this.generateAuthorization(config.getAccessKeyId(), timestamp)) - .body(JSONUtil.toJsonStr(paramMap)) - .execute()){ - JSONObject body = JSONUtil.parseObj(response.body()); - return this.getResponse(body); + String url = String.format("%s/Accounts/%s/SMS/TemplateSMS?sig=%s", + config.getBaseUrl(), + config.getAccessKeyId(), + this.generateSign(config.getAccessKeyId(), config.getAccessKeySecret(), timestamp)); + Map headers = new LinkedHashMap<>(3); + headers.put("Accept", Constant.ACCEPT); + headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); + headers.put("Authorization", this.generateAuthorization(config.getAccessKeyId(), timestamp)); + SmsResponse smsResponse = getResponse(http.postJson(url, headers, paramMap)); + if(smsResponse.isSuccess() || retry == config.getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(paramMap); + }catch (SmsBlendException e){ + return requestRetry(paramMap); } } + private SmsResponse requestRetry(Map paramMap) { + http.safeSleep(config.getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return smsResponse(paramMap); + } + private SmsResponse getResponse(JSONObject resJson) { SmsResponse smsResponse = new SmsResponse(); smsResponse.setSuccess("000000".equals(resJson.getStr("statusCode"))); 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 index 11350e33..09419b5c 100644 --- 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 @@ -1,7 +1,5 @@ package org.dromara.sms4j.ctyun.service; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; @@ -29,6 +27,8 @@ public class CtyunSmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "ctyun"; + private int retry = 0; + public CtyunSmsImpl(CtyunConfig config, Executor pool, DelayedTime delayedTime) { super(config, pool, delayedTime); } @@ -44,7 +44,7 @@ public class CtyunSmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { - LinkedHashMap map = new LinkedHashMap<>(); + LinkedHashMap map = new LinkedHashMap<>(1); map.put(getConfig().getTemplateName(), message); return sendMessage(phone, getConfig().getTemplateId(), map); } @@ -57,7 +57,7 @@ public class CtyunSmsImpl extends AbstractSmsBlend { @Override public SmsResponse massTexting(List phones, String message) { - LinkedHashMap map = new LinkedHashMap<>(); + LinkedHashMap map = new LinkedHashMap<>(1); map.put(getConfig().getTemplateName(), message); return massTexting(phones, getConfig().getTemplateId(), map); } @@ -79,15 +79,27 @@ public class CtyunSmsImpl extends AbstractSmsBlend { throw new SmsBlendException(e.getMessage()); } log.debug("requestUrl {}", requestUrl); - try(HttpResponse response = HttpRequest.post(requestUrl) - .addHeaders(CtyunUtils.signHeader(paramStr, getConfig().getAccessKeyId(), getConfig().getAccessKeySecret())) - .body(paramStr) - .execute()){ - JSONObject body = JSONUtil.parseObj(response.body()); - return this.getResponse(body); + try { + SmsResponse smsResponse = getResponse(http.postJson(requestUrl, + CtyunUtils.signHeader(paramStr, getConfig().getAccessKeyId(), getConfig().getAccessKeySecret()), + paramStr)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phone, message, templateId); + }catch (SmsBlendException e){ + return requestRetry(phone, message, templateId); } } + private SmsResponse requestRetry(String phone, String message, String templateId) { + http.safeSleep(getConfig().getRetryInterval()); + retry ++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return getSmsResponse(phone, message, templateId); + } + private SmsResponse getResponse(JSONObject resJson) { SmsResponse smsResponse = new SmsResponse(); smsResponse.setSuccess("OK".equals(resJson.getStr("code"))); 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 index 7f021719..5f4af767 100644 --- 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 @@ -6,6 +6,7 @@ import cn.hutool.crypto.digest.HmacAlgorithm; import cn.hutool.json.JSONUtil; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.exception.SmsBlendException; import org.dromara.sms4j.ctyun.config.CtyunConfig; @@ -35,7 +36,7 @@ public class CtyunUtils { * 获取签名请求头 */ public static Map signHeader(String body, String key, String secret){ - Map map = new ConcurrentHashMap<>(); + Map map = new ConcurrentHashMap<>(4); // 构造时间戳 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); @@ -58,7 +59,7 @@ public class CtyunUtils { // 构造签名 String signature = Base64.encode(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("Content-Type", Constant.APPLICATION_JSON_UTF8); map.put("ctyun-eop-request-id", uuid); map.put("Eop-date", signatureTime); map.put("Eop-Authorization", signHeader); @@ -74,7 +75,7 @@ public class CtyunUtils { * @param templateId 模板id */ public static String generateParamJsonStr(CtyunConfig ctyunConfig, String phone, String message, String templateId) { - Map paramMap = new HashMap<>(); + Map paramMap = new HashMap<>(5); paramMap.put("action", ctyunConfig.getAction()); paramMap.put("phoneNumber", phone); paramMap.put("signName", ctyunConfig.getSignature()); 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 bfd4ca6a..1738dbb0 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,11 +1,9 @@ package org.dromara.sms4j.emay.service; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +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; @@ -27,6 +25,7 @@ import java.util.concurrent.Executor; public class EmaySmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "emay"; + private int retry = 0; public EmaySmsImpl(EmayConfig config, Executor pool, DelayedTime delayed) { super(config, pool, delayed); @@ -44,17 +43,29 @@ public class EmaySmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { String url = getConfig().getRequestUrl(); - Map params; + Map params = EmayBuilder.buildRequestBody(getConfig().getAccessKeyId(), getConfig().getAccessKeySecret(), phone, message); try { - params = EmayBuilder.buildRequestBody(getConfig().getAccessKeyId(), getConfig().getAccessKeySecret(), phone, message); - } catch (SmsBlendException e) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - return smsResponse; + Map headers = new LinkedHashMap<>(1); + headers.put("Content-Type", Constant.FROM_URLENCODED); + SmsResponse smsResponse = getResponse(http.postJson(url, headers, params)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phone, message); + }catch (SmsBlendException e){ + return requestRetry(phone, message); } - return getSendResponse(params, url); } + private SmsResponse requestRetry(String phone, String message) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return sendMessage(phone, message); + } + + @Override public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { List list = new ArrayList<>(); @@ -84,16 +95,6 @@ public class EmaySmsImpl extends AbstractSmsBlend { return sendMessage(SmsUtil.listToString(phones), EmayBuilder.listToString(list)); } - private SmsResponse getSendResponse(Map body, String requestUrl) { - try(HttpResponse response = HttpRequest.post(requestUrl) - .header("Content-Type", "application/x-www-form-urlencoded") - .body(JSONUtil.toJsonStr(body)) - .execute()){ - JSONObject res = JSONUtil.parseObj(response.body()); - return this.getResponse(res); - } - } - private SmsResponse getResponse(JSONObject resJson) { SmsResponse smsResponse = new SmsResponse(); smsResponse.setSuccess("success".equalsIgnoreCase(resJson.getStr("code"))); 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 fce192a6..1d8ef67b 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,13 +1,11 @@ package org.dromara.sms4j.huawei.service; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; 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.huawei.config.HuaweiConfig; import org.dromara.sms4j.huawei.utils.HuaweiBuilder; import org.dromara.sms4j.provider.service.AbstractSmsBlend; @@ -21,6 +19,7 @@ import static org.dromara.sms4j.huawei.utils.HuaweiBuilder.listToString; public class HuaweiSmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "huawei"; + private int retry = 0; public HuaweiSmsImpl(HuaweiConfig config, Executor pool, DelayedTime delayed) { super(config, pool, delayed); @@ -51,19 +50,29 @@ public class HuaweiSmsImpl extends AbstractSmsBlend { } String mess = listToString(list); String requestBody = HuaweiBuilder.buildRequestBody(getConfig().getSender(), phone, templateId, mess, getConfig().getStatusCallBack(), getConfig().getSignature()); - Map headers = new LinkedHashMap<>(); - headers.put("Authorization", Constant.HUAWEI_AUTH_HEADER_VALUE); - headers.put("X-WSSE", HuaweiBuilder.buildWsseHeader(getConfig().getAccessKeyId(), getConfig().getAccessKeySecret())); - headers.put("Content-Type", Constant.FROM_URLENCODED); - try(HttpResponse response = HttpRequest.post(url) - .addHeaders(headers) - .body(requestBody) - .execute()){ - JSONObject body = JSONUtil.parseObj(response.body()); - return this.getResponse(body); + try { + Map headers = new LinkedHashMap<>(3); + headers.put("Authorization", Constant.HUAWEI_AUTH_HEADER_VALUE); + headers.put("X-WSSE", HuaweiBuilder.buildWsseHeader(getConfig().getAccessKeyId(), getConfig().getAccessKeySecret())); + headers.put("Content-Type", Constant.FROM_URLENCODED); + SmsResponse smsResponse = getResponse(http.postJson(url, headers, requestBody)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phone, templateId, messages); + }catch (SmsBlendException e){ + return requestRetry(phone, templateId, messages); } } + private SmsResponse requestRetry(String phone, String templateId, LinkedHashMap messages) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return sendMessage(phone, templateId, messages); + } + @Override public SmsResponse massTexting(List phones, String message) { return sendMessage(listToString(phones), message); 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 425a707e..fc283e15 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 @@ -30,6 +30,8 @@ public class JdCloudSmsImpl extends AbstractSmsBlend { private final SmsClient client; + private int retry = 0; + public JdCloudSmsImpl(SmsClient client, JdCloudConfig config, Executor pool, DelayedTime delayed) { super(config, pool, delayed); this.client = client; @@ -64,8 +66,9 @@ public class JdCloudSmsImpl extends AbstractSmsBlend { @Override public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { + BatchSendRequest request; try { - BatchSendRequest request = new BatchSendRequest(); + request = new BatchSendRequest(); request.setPhoneList(phones); request.setRegionId(getConfig().getRegion()); request.setTemplateId(templateId); @@ -73,12 +76,28 @@ public class JdCloudSmsImpl extends AbstractSmsBlend { List params = messages.keySet().stream().map(messages::get) .collect(Collectors.toList()); request.setParams(params); - - BatchSendResult result = client.batchSend(request).getResult(); - return getSmsResponse(result); } catch (Exception e) { throw new SmsBlendException(e.getMessage()); } + + try { + BatchSendResult result = client.batchSend(request).getResult(); + SmsResponse smsResponse = getSmsResponse(result); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phones, templateId, messages); + }catch (SmsBlendException e){ + return requestRetry(phones, templateId, messages); + } + } + + private SmsResponse requestRetry(List phones, String templateId, LinkedHashMap messages) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return massTexting(phones, templateId, messages); } /** diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java index 1bcdca76..6338c0dc 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java @@ -2,13 +2,11 @@ package org.dromara.sms4j.netease.service; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +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.netease.config.NeteaseConfig; @@ -29,6 +27,7 @@ import java.util.concurrent.Executor; public class NeteaseSmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "netease"; + private int retry = 0; public NeteaseSmsImpl(NeteaseConfig config, Executor pool, DelayedTime delayed) { super(config, pool, delayed); @@ -98,24 +97,37 @@ public class NeteaseSmsImpl extends AbstractSmsBlend { String checkSum = NeteaseUtils.getCheckSum(getConfig().getAccessKeySecret(), nonce, curTime); Map body = new LinkedHashMap<>(4); body.put("templateid", templateId); - JSONArray jsonArray = JSONUtil.createArray(); + JSONArray jsonArray = new JSONArray(); jsonArray.addAll(phones); body.put("mobiles", jsonArray.toString()); body.put("params", message); body.put("needUp", getConfig().getNeedUp()); - try(HttpResponse response = HttpRequest.post(requestUrl) - .header("Content-Type", "application/x-www-form-urlencoded") - .header("AppKey", getConfig().getAccessKeyId()) - .header("Nonce", nonce) - .header("CurTime", curTime) - .header("CheckSum", checkSum) - .body(JSONUtil.toJsonStr(body)) - .execute()){ - JSONObject res = JSONUtil.parseObj(response.body()); - return this.getResponse(res); + + try { + Map headers = new LinkedHashMap<>(5); + headers.put("Content-Type", Constant.FROM_URLENCODED); + headers.put("AppKey", getConfig().getAccessKeyId()); + headers.put("Nonce", nonce); + headers.put("CurTime", curTime); + headers.put("CheckSum", checkSum); + SmsResponse smsResponse = getResponse(http.postJson(requestUrl, headers, body)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(requestUrl, phones, message, templateId); + }catch (SmsBlendException e){ + return requestRetry(requestUrl, phones, message, templateId); } } + private SmsResponse requestRetry(String requestUrl, List phones, String message, String templateId) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return getSmsResponse(requestUrl, phones, message, templateId); + } + private SmsResponse getResponse(JSONObject jsonObject) { SmsResponse smsResponse = new SmsResponse(); smsResponse.setSuccess(jsonObject.getInt("code") <= 200); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java index 6bb4eb3e..983bec5e 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java @@ -1,10 +1,8 @@ package org.dromara.sms4j.provider.config; -import lombok.Builder; import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; import org.dromara.sms4j.api.universal.SupplierConfig; +import org.dromara.sms4j.comm.exception.SmsBlendException; /** * 短信配置属性基类 @@ -48,4 +46,27 @@ public abstract class BaseConfig implements SupplierConfig { */ private String configId; + /** + * 重试间隔(单位:秒),默认为5秒 + */ + private int retryInterval = 5; + + public void setRetryInterval(int retryInterval) { + if (retryInterval <= 0){ + throw new SmsBlendException("重试间隔必须大于0秒"); + } + this.retryInterval = retryInterval; + } + + /** + * 重试次数,默认为0次 + */ + private int maxRetries = 0; + + public void setMaxRetries(int maxRetries) { + if (maxRetries < 0){ + throw new SmsBlendException("重试次数不能小于0次"); + } + this.maxRetries = maxRetries; + } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java index e1307bb6..fef20cf2 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java @@ -8,6 +8,7 @@ import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.api.universal.SupplierConfig; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.factory.BeanFactory; +import org.dromara.sms4j.comm.utils.SmsHttpUtil; import java.util.LinkedHashMap; import java.util.List; @@ -26,6 +27,8 @@ public abstract class AbstractSmsBlend implements SmsB protected final DelayedTime delayed; + protected final SmsHttpUtil http = SmsHttpUtil.instance(); + protected AbstractSmsBlend(C config, Executor pool, DelayedTime delayed) { this.configId = StrUtil.isEmpty(config.getConfigId()) ? getSupplier() : config.getConfigId(); this.config = config; 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 6f4e5752..df04b80c 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,9 +1,6 @@ package org.dromara.sms4j.tencent.service; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; import com.jdcloud.sdk.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; @@ -28,6 +25,7 @@ import java.util.concurrent.Executor; public class TencentSmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "alibaba"; + private int retry = 0; public TencentSmsImpl(TencentConfig tencentSmsConfig, Executor pool, DelayedTime delayed) { super(tencentSmsConfig, pool, delayed); @@ -96,15 +94,26 @@ public class TencentSmsImpl extends AbstractSmsBlend { Map requestBody = TencentUtils.generateRequestBody(phones, getConfig().getSdkAppId(), getConfig().getSignature(), templateId, messages); String url = Constant.HTTPS_PREFIX + getConfig().getRequestUrl(); - try(HttpResponse response = HttpRequest.post(url) - .addHeaders(headsMap) - .body(JSONUtil.toJsonStr(requestBody)) - .execute()){ - JSONObject body = JSONUtil.parseObj(response.body()); - return this.getResponse(body); + + try { + SmsResponse smsResponse = getResponse(http.postJson(url, headsMap, requestBody)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phones, messages, templateId); + }catch (SmsBlendException e){ + return requestRetry(phones, messages, templateId); } } + private SmsResponse requestRetry(String[] phones, String[] messages, String templateId) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return getSmsResponse(phones, messages, templateId); + } + private SmsResponse getResponse(JSONObject resJson) { SmsResponse smsResponse = new SmsResponse(); JSONObject response = resJson.getJSONObject("Response"); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/Uni.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/Uni.java index e6491d99..1a807b80 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/Uni.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/Uni.java @@ -61,11 +61,11 @@ public class Uni { * @return the Uni Client * @author :Wind */ - public static UniClient getClient() { + public static UniClient getClient(int retryInterval, int maxRetries) { if (Uni.client == null) { synchronized (Uni.class) { if (Uni.client == null) { - Uni.client = buildClient(); + Uni.client = buildClient(retryInterval, maxRetries); } } } @@ -78,7 +78,7 @@ public class Uni { } } - private static UniClient buildClient() { + private static UniClient buildClient(int retryInterval, int maxRetries) { UniClient.Builder builder = new UniClient.Builder(Uni.accessKeyId); if (Uni.accessKeySecret != null) { @@ -87,7 +87,8 @@ public class Uni { builder.endpoint(Uni.endpoint); builder.signingAlgorithm(Uni.signingAlgorithm); - + builder.setRetryInterval(retryInterval); + builder.setMaxRetries(maxRetries); return builder.build(); } } 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 b5500ed5..0918c042 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 @@ -3,10 +3,10 @@ package org.dromara.sms4j.unisms.core; import cn.hutool.core.codec.Base64; import cn.hutool.crypto.digest.HMac; import cn.hutool.crypto.digest.HmacAlgorithm; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; -import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.exception.SmsBlendException; +import org.dromara.sms4j.comm.utils.SmsHttpUtil; import java.util.Comparator; import java.util.Date; @@ -17,6 +17,7 @@ import java.util.Map.Entry; import java.util.TreeMap; import java.util.UUID; +@Slf4j public class UniClient { public static final String USER_AGENT = "uni-java-sdk" + "/" + Uni.VERSION; @@ -24,12 +25,18 @@ public class UniClient { private final String accessKeySecret; private final String endpoint; private final String signingAlgorithm; + private final int retryInterval; + private final int maxRetries; + private int retry = 0; + private final SmsHttpUtil http = SmsHttpUtil.instance(); protected UniClient(Builder b) { this.accessKeyId = b.accessKeyId; this.accessKeySecret = b.accessKeySecret; this.endpoint = b.endpoint; this.signingAlgorithm = b.signingAlgorithm; + this.retryInterval = b.retryInterval; + this.maxRetries = b.maxRetries; } private static String getSignature(final String message, final String secretKey) { @@ -81,23 +88,37 @@ public class UniClient { public UniResponse request(final String action, final Map data) throws SmsBlendException { Map headers = new HashMap<>(); headers.put("User-Agent", USER_AGENT); - headers.put("Content-Type", "application/json;charset=utf-8"); - headers.put("Accept", "application/json"); + headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); + headers.put("Accept", Constant.ACCEPT); String url = this.endpoint + "?action=" + action + "&accessKeyId=" + this.accessKeyId; - try(HttpResponse response = HttpRequest.post(url) - .addHeaders(headers) - .body(JSONUtil.toJsonStr(data)) - .execute()){ - return new UniResponse(JSONUtil.parseObj(response.body())); + + try { + UniResponse smsResponse = new UniResponse(http.postJson(url, headers, data)); + if("Success".equals(smsResponse.message) || retry == maxRetries){ + retry = 0; + return smsResponse; + } + return requestRetry(action, data); + }catch (SmsBlendException e){ + return requestRetry(action, data); } } + private UniResponse requestRetry(String action, Map data) { + http.safeSleep(retryInterval); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return request(action, data); + } + public static class Builder { private String accessKeyId; private String accessKeySecret; private String endpoint; private String signingAlgorithm; + private int retryInterval; + private int maxRetries; public Builder(final String accessKeyId) { this.accessKeyId = accessKeyId; @@ -123,6 +144,16 @@ public class UniClient { return this; } + public Builder setRetryInterval(int retryInterval) { + this.retryInterval = retryInterval; + return this; + } + + public Builder setMaxRetries(int maxRetries) { + this.maxRetries = maxRetries; + return this; + } + public UniClient build() { return new UniClient(this); } 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 7e86a0f0..8f8a1e18 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 @@ -27,7 +27,7 @@ public class UniResponse { this.raw = body; this.data = body; } - if (this.status != "400") { + if (!"400".equals(this.status)) { String code = response.getStr("code"); if (!"0".equals(code)) { this.message = response.getStr("message"); 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 7fd067dc..3290b2ea 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 @@ -42,14 +42,14 @@ public class UniSmsImpl extends AbstractSmsBlend { if ("".equals(getConfig().getTemplateId()) && "".equals(getConfig().getTemplateName())) { throw new SmsBlendException("配置文件模板id和模板变量不能为空!"); } - LinkedHashMap map = new LinkedHashMap<>(); + LinkedHashMap map = new LinkedHashMap<>(1); map.put(getConfig().getTemplateName(), message); return sendMessage(phone, getConfig().getTemplateId(), map); } @Override public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { - Map data = new HashMap<>(); + Map data = new LinkedHashMap<>(4); data.put("to", Collections.singletonList(phone)); data.put("signature", getConfig().getSignature()); data.put("templateId", templateId); @@ -62,7 +62,7 @@ public class UniSmsImpl extends AbstractSmsBlend { if ("".equals(getConfig().getTemplateId()) && "".equals(getConfig().getTemplateName())) { throw new SmsBlendException("配置文件模板id和模板变量不能为空!"); } - LinkedHashMap map = new LinkedHashMap<>(); + LinkedHashMap map = new LinkedHashMap<>(1); map.put(getConfig().getTemplateName(), message); return massTexting(phones, getConfig().getTemplateId(), map); } @@ -72,7 +72,7 @@ public class UniSmsImpl extends AbstractSmsBlend { if (phones.size() > 1000) { throw new SmsBlendException("单次发送超过最大发送上限,建议每次群发短信人数低于1000"); } - Map data = new HashMap<>(); + Map data = new LinkedHashMap<>(4); data.put("to", phones); data.put("signature", getConfig().getSignature()); data.put("templateId", templateId); @@ -83,7 +83,7 @@ public class UniSmsImpl extends AbstractSmsBlend { private SmsResponse getSmsResponse(Map data) { SmsResponse smsResponse = new SmsResponse(); try { - UniResponse send = Uni.getClient().request("sms.message.send", data); + UniResponse send = Uni.getClient(getConfig().getRetryInterval(), getConfig().getMaxRetries()).request("sms.message.send", data); smsResponse.setSuccess("Success".equals(send.message)); smsResponse.setData(send); smsResponse.setConfigId(getConfigId()); 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 6060a9c2..72b0f14f 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,9 +1,7 @@ package org.dromara.sms4j.yunpian.service; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -21,9 +19,11 @@ import java.util.concurrent.Executor; /** * @author wind */ +@Slf4j public class YunPianSmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "yunpian"; + private int retry = 0; public YunPianSmsImpl(YunpianConfig config, Executor pool, DelayedTime delayed) { super(config, pool, delayed); @@ -52,14 +52,50 @@ public class YunPianSmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { - Map body = setBody(phone, message, null, getConfig().getTemplateId()); - return getSendResponse(body); + Map body = setBody(phone, message, null, getConfig().getTemplateId()); + Map headers = getHeaders(); + + try { + SmsResponse smsResponse = getResponse(http.postJson(Constant.YUNPIAN_URL + "/sms/tpl_single_send.json", headers, body)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phone, message); + }catch (SmsBlendException e){ + return requestRetry(phone, message); + } + } + + private SmsResponse requestRetry(String phone, String message) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return sendMessage(phone, message); } @Override public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { - Map body = setBody(phone, "", messages, templateId); - return getSendResponse(body); + Map body = setBody(phone, "", messages, templateId); + Map headers = getHeaders(); + + try { + SmsResponse smsResponse = getResponse(http.postJson(Constant.YUNPIAN_URL + "/sms/tpl_single_send.json", headers, body)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phone, templateId, messages); + }catch (SmsBlendException e){ + return requestRetry(phone, templateId, messages); + } + } + + private SmsResponse requestRetry(String phone, String templateId, LinkedHashMap messages) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return sendMessage(phone, templateId, messages); } @Override @@ -91,14 +127,14 @@ public class YunPianSmsImpl extends AbstractSmsBlend { return str.toString(); } - private Map setBody(String phone, String mes, LinkedHashMap messages, String tplId) { + private Map setBody(String phone, String mes, LinkedHashMap messages, String tplId) { LinkedHashMap message = new LinkedHashMap<>(); if (mes.isEmpty()) { message = messages; } else { message.put(getConfig().getTemplateName(), mes); } - Map body = new HashMap<>(); + Map body = new HashMap<>(); body.put("apikey", getConfig().getAccessKeyId()); body.put("mobile", phone); body.put("tpl_id", tplId); @@ -110,19 +146,8 @@ public class YunPianSmsImpl extends AbstractSmsBlend { private Map getHeaders() { Map headers = new HashMap<>(); - headers.put("Accept", "application/json;charset=utf-8"); + headers.put("Accept", Constant.APPLICATION_JSON_UTF8); headers.put("Content-Type", Constant.FROM_URLENCODED); return headers; } - - private SmsResponse getSendResponse(Map body) { - Map headers = getHeaders(); - try(HttpResponse response = HttpRequest.post(Constant.YUNPIAN_URL + "/sms/tpl_single_send.json") - .addHeaders(headers) - .body(JSONUtil.toJsonStr(body)) - .execute()){ - JSONObject res = JSONUtil.parseObj(response.body()); - return getResponse(res); - } - } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java index d1510094..ff7d0a76 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java @@ -5,11 +5,8 @@ import cn.hutool.core.collection.ListUtil; import cn.hutool.core.text.StrPool; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.comm.constant.Constant; @@ -33,6 +30,7 @@ import java.util.concurrent.Executor; public class ZhutongSmsImpl extends AbstractSmsBlend { public static final String SUPPLIER = "zhutong"; + private int retry = 0; /** * ZhutongSmsImpl @@ -63,7 +61,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { return getSmsResponse(phone, message); } - LinkedHashMap map = new LinkedHashMap<>(); + LinkedHashMap map = new LinkedHashMap<>(1); map.put(config.getTemplateName(), message); return sendMessage(phone, config.getTemplateId(), map); } @@ -81,7 +79,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { return getSmsResponse(phones, message); } - LinkedHashMap map = new LinkedHashMap<>(); + LinkedHashMap map = new LinkedHashMap<>(1); map.put(config.getTemplateName(), message); return massTexting(phones, config.getTemplateId(), map); } @@ -120,7 +118,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { String url = requestUrl + "v2/sendSms"; long tKey = System.currentTimeMillis() / 1000; - Map json = new HashMap<>(5); + Map json = new HashMap<>(5); //账号 json.put("username", username); //密码 @@ -132,15 +130,27 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { //内容 json.put("content", content); - try(HttpResponse response = HttpRequest.post(url) - .header("Content-Type", Constant.APPLICATION_JSON_UTF8) - .body(JSONUtil.toJsonStr(json)) - .execute()){ - JSONObject body = JSONUtil.parseObj(response.body()); - return this.getResponse(body); + try { + Map headers = new LinkedHashMap<>(1); + headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); + SmsResponse smsResponse = getResponse(http.postJson(requestUrl, headers, json)); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(phones, content); + }catch (SmsBlendException e){ + return requestRetry(phones, content); } } + private SmsResponse requestRetry(List phones, String content) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return getSmsResponse(phones, content); + } + protected SmsResponse getSmsResponse(String mobile, String content) { return getSmsResponse(ListUtil.of(mobile), content); } @@ -205,15 +215,27 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { } requestJson.set("records", records); - try(HttpResponse response = HttpRequest.post(url) - .header("Content-Type", Constant.APPLICATION_JSON_UTF8) - .body(requestJson.toString()) - .execute()){ - JSONObject body = JSONUtil.parseObj(response.body()); - return this.getResponse(body); + try { + Map headers = new LinkedHashMap<>(1); + headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); + SmsResponse smsResponse = getResponse(http.postJson(requestUrl, headers, requestJson.toString())); + if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){ + retry = 0; + return smsResponse; + } + return requestRetry(templateId, phones, messages); + }catch (SmsBlendException e){ + return requestRetry(templateId, phones, messages); } } + private SmsResponse requestRetry(String templateId, List phones, LinkedHashMap messages) { + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return getSmsResponseTemplate(templateId, phones, messages); + } + protected SmsResponse getSmsResponseTemplate(String templateId, String mobile, LinkedHashMap content) { return getSmsResponseTemplate(templateId, ListUtil.of(mobile), content); }