From bea0c20e6739c9f90c2c9f6e4590eb0ef6dc3288 Mon Sep 17 00:00:00 2001 From: bleachtred Date: Mon, 13 May 2024 00:43:55 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/sms4j/comm/utils/SmsUtils.java | 43 ++- .../sms4j/javase/config/SEInitializer.java | 4 +- .../chuanglan/service/ChuangLanSmsImpl.java | 19 +- .../org/dromara/sms4j/jg/config/JgConfig.java | 71 +++++ .../config/JgFactory.java} | 16 +- .../dromara/sms4j/jg/service/JgSmsImpl.java | 145 ++++++++++ .../org/dromara/sms4j/jg/util/JgHelper.java | 262 ++++++++++++++++++ .../sms4j/jiguang/config/JiguangConfig.java | 79 ------ .../sms4j/jiguang/service/JiguangSmsImpl.java | 192 ------------- .../sms4j/jiguang/util/JiGuangHelper.java | 72 ----- .../sms4j/tencent/service/TencentSmsImpl.java | 36 +-- .../solon/config/SmsBlendsInitializer.java | 4 +- .../org/dromara/sms4j/example/Sms4jTest.java | 44 +-- .../starter/config/SmsBlendsInitializer.java | 4 +- 14 files changed, 556 insertions(+), 435 deletions(-) create mode 100644 sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgConfig.java rename sms4j-provider/src/main/java/org/dromara/sms4j/{jiguang/config/JiguangFactory.java => jg/config/JgFactory.java} (62%) create mode 100644 sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java create mode 100644 sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgHelper.java delete mode 100644 sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/config/JiguangConfig.java delete mode 100644 sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/service/JiguangSmsImpl.java delete mode 100644 sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/util/JiGuangHelper.java diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java index b4f3de24..455ba89a 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java @@ -7,10 +7,8 @@ import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Predicate; /** * @author wind @@ -144,20 +142,20 @@ public class SmsUtils { /** * 将Map中所有key的分隔符转换为新的分隔符 * @param map map对象 - * @param seperator 旧分隔符 - * @param newSeperator 新分隔符 + * @param separator 旧分隔符 + * @param newSeparator 新分隔符 */ - public static void replaceKeysSeperator(Map map, String seperator, String newSeperator) { + public static void replaceKeysSeparator(Map map, String separator, String newSeparator) { if(CollUtil.isEmpty(map)) { return; } List keySet = new ArrayList<>(map.keySet()); for(String key : keySet) { - if(StrUtil.isEmpty(key) || !key.contains(seperator)) { + if(StrUtil.isEmpty(key) || !key.contains(separator)) { continue; } String value = String.valueOf(map.get(key)); - String newKey = key.replaceAll(seperator, newSeperator); + String newKey = key.replaceAll(separator, newSeparator); map.putIfAbsent(newKey, value); map.remove(key); } @@ -172,4 +170,31 @@ public class SmsUtils { } } + public static LinkedHashMap buildMessageByAmpersand(String message) { + if (isEmpty(message)){ + return new LinkedHashMap<>(); + } + String[] split = message.split("&"); + LinkedHashMap map = new LinkedHashMap<>(split.length); + for (int i = 0; i < split.length; i++) { + map.put(String.valueOf(i), split[i]); + } + return map; + } + + /** + * 将任意类型集合转成想要的数组 + * @param list 需要转换的集合 + * @param predicate 过滤条件 + * @param array 想要的数组 + * @return 数组 + * @param 集合泛型 + * @param 想要的数组类型 + */ + public static E[] toArray(Collection list, Predicate predicate, E[] array) { + if (isEmpty(list)) { + return array.clone(); + } + return list.stream().filter(predicate).toArray(size -> array.clone()); + } } \ No newline at end of file diff --git a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java index e08c836e..be3a312a 100644 --- a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java +++ b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java @@ -37,7 +37,7 @@ import org.dromara.sms4j.huawei.config.HuaweiFactory; import org.dromara.sms4j.javase.util.YamlUtils; import org.dromara.sms4j.jdcloud.config.JdCloudFactory; import org.dromara.sms4j.chuanglan.config.ChuangLanFactory; -import org.dromara.sms4j.jiguang.config.JiguangFactory; +import org.dromara.sms4j.jg.config.JgFactory; import org.dromara.sms4j.lianlu.config.LianLuFactory; import org.dromara.sms4j.mas.config.MasFactory; import org.dromara.sms4j.netease.config.NeteaseFactory; @@ -258,7 +258,7 @@ public class SEInitializer { ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); ProviderFactoryHolder.registerFactory(ChuangLanFactory.instance()); - ProviderFactoryHolder.registerFactory(JiguangFactory.instance()); + ProviderFactoryHolder.registerFactory(JgFactory.instance()); ProviderFactoryHolder.registerFactory(QiNiuFactory.instance()); ProviderFactoryHolder.registerFactory(BudingV2Factory.instance()); ProviderFactoryHolder.registerFactory(MasFactory.instance()); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java index 1f054b8a..ad1cb1d6 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java @@ -6,6 +6,7 @@ import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.chuanglan.config.ChuangLanConfig; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; +import org.dromara.sms4j.comm.utils.SmsUtils; import org.dromara.sms4j.provider.service.AbstractSmsBlend; import java.util.Collection; @@ -38,12 +39,7 @@ public class ChuangLanSmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { - String[] split = message.split("&"); - LinkedHashMap map = new LinkedHashMap<>(); - for (int i = 0; i < split.length; i++) { - map.put(String.valueOf(i), split[i]); - } - return sendMessage(phone, getConfig().getTemplateId(), map); + return sendMessage(phone, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); } @Override @@ -70,12 +66,7 @@ public class ChuangLanSmsImpl extends AbstractSmsBlend { @Override public SmsResponse massTexting(List phones, String message) { - LinkedHashMap messages = new LinkedHashMap<>(); - String[] split = message.split("&"); - for (int i = 0; i < split.length; i++) { - messages.put(String.valueOf(i), split[i]); - } - return massTexting(phones, getConfig().getTemplateId(), messages); + return massTexting(phones, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); } @Override @@ -86,9 +77,7 @@ public class ChuangLanSmsImpl extends AbstractSmsBlend { String message = String.join(",", values); StringBuilder param = new StringBuilder(); - phones.forEach(phone -> { - param.append(phone).append(",").append(message).append(";"); - }); + phones.forEach(phone -> param.append(phone).append(",").append(message).append(";")); LinkedHashMap params = new LinkedHashMap<>(); params.put("account", getConfig().getAccessKeyId()); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgConfig.java new file mode 100644 index 00000000..82ac7de1 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgConfig.java @@ -0,0 +1,71 @@ +package org.dromara.sms4j.jg.config; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.provider.config.BaseConfig; + +/** + *

类名: JgConfig + *

说明:极光 sms + * + * @author :SmartFire + * 2024/3/15 + **/ +@Data +@EqualsAndHashCode(callSuper = true) +public class JgConfig extends BaseConfig { + /** + * 签名 ID,该字段为空则使用应用默认签名 + */ + private String signId; + + /** + * 调用地址 + */ + private String requestUrl = "https://api.sms.jpush.cn/v1/"; + + /** + * 默认请求方法 messages + * 发送文本验证码短信 codes + * 发送语音验证码短信 voice_codes + * 验证验证码是否有效 valid + * 注意:此处直接写valid即为验证码验证请求 系统会自动补充完整请求地址为codes/{msg_id}/valid (注:msg_id 为调用发送验证码 API 的返回值) + * 发送单条模板短信 messages + * 发送批量模板短信 messages/batch + */ + private String action = "messages"; + + /** + * 模板变量名称 + */ + private String templateName; + + /** + * action设置为voice_codes有效 + * 语音验证码播报语言选择,0:中文播报,1:英文播报,2:中英混合播报 + */ + private String voice; + + /** + * action设置为voice_codes有效 + * 验证码有效期,默认为 60 秒 + */ + private Integer ttl = 60; + + /** + * action设置为messages/batch有效 + * 标签 + */ + private String tag; + + /** + * 获取供应商 + * + * @since 3.0.0 + */ + @Override + public String getSupplier() { + return SupplierConstant.JIGUANG; + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/config/JiguangFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgFactory.java similarity index 62% rename from sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/config/JiguangFactory.java rename to sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgFactory.java index d51897ae..0ca36aa5 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/config/JiguangFactory.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgFactory.java @@ -1,28 +1,28 @@ -package org.dromara.sms4j.jiguang.config; +package org.dromara.sms4j.jg.config; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.dromara.sms4j.comm.constant.SupplierConstant; -import org.dromara.sms4j.jiguang.service.JiguangSmsImpl; +import org.dromara.sms4j.jg.service.JgSmsImpl; import org.dromara.sms4j.provider.factory.AbstractProviderFactory; /** - *

类名: JiguangFactory + *

类名: JgFactory *

说明:极光 sms * * @author :SmartFire * 2024/3/15 **/ @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class JiguangFactory extends AbstractProviderFactory { +public class JgFactory extends AbstractProviderFactory { - private static final JiguangFactory INSTANCE = new JiguangFactory(); + private static final JgFactory INSTANCE = new JgFactory(); /** * 获取建造者实例 * @return 建造者实例 */ - public static JiguangFactory instance() { + public static JgFactory instance() { return INSTANCE; } @@ -32,8 +32,8 @@ public class JiguangFactory extends AbstractProviderFactory类名: JgSmsImpl + *

说明:极光 sms + * + * @author :SmartFire + * 2024/3/15 + **/ +@Slf4j +public class JgSmsImpl extends AbstractSmsBlend { + private int retry = 0; + + public JgSmsImpl(JgConfig config, Executor pool, DelayedTime delayedTime) { + super(config, pool, delayedTime); + } + + public JgSmsImpl(JgConfig config) { + super(config); + } + + @Override + public String getSupplier() { + return SupplierConstant.JIGUANG; + } + + @Override + public SmsResponse sendMessage(String phone, String message) { + LinkedHashMap map = new LinkedHashMap<>(1); + if (SmsUtils.isNotEmpty(getConfig().getTemplateName()) && + SmsUtils.isNotEmpty(message)){ + map.put(getConfig().getTemplateName(), message); + } + return sendMessage(phone, getConfig().getTemplateId(), map); + } + + @Override + public SmsResponse sendMessage(String phone, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + return sendMessage(phone, getConfig().getTemplateId(), messages); + } + + @Override + public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + return getSmsResponse(phone, messages, templateId, null, null); + } + + @Override + public SmsResponse massTexting(List phones, String message) { + LinkedHashMap map = new LinkedHashMap<>(1); + if (SmsUtils.isNotEmpty(getConfig().getTemplateName()) && + SmsUtils.isNotEmpty(message)){ + map.put(getConfig().getTemplateName(), message); + } + return massTexting(phones, getConfig().getTemplateId(), map); + } + + @Override + public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + return getSmsResponse(SmsUtils.arrayToString(phones), messages, templateId, null, null); + } + + /** + * 自定义方法 + * 发送语音验证码短信 请确保action配置为voice_codes + * @param phone 手机号 + * @param code 语音验证码 可不填 + */ + public SmsResponse sendVoiceCode(String phone, String code){ + return getSmsResponse(phone, null, null, code, null); + } + + /** + * 自定义方法 + * 验证验证码是否有效 请确保action配置为voice_codes + * @param msgId 为调用发送验证码 API 的返回值 + * @param code 验证码 + */ + public SmsResponse verifyCode(String code, String msgId){ + return getSmsResponse(null, null, null, code, msgId); + } + + private SmsResponse getSmsResponse(String phone, LinkedHashMap messages, + String templateId, String code, String msgId) { + SmsResponse smsResponse; + JgConfig config = getConfig(); + String url = JgHelper.buildUrl(config.getRequestUrl(), config.getAction(), msgId); + Map headers = JgHelper.buildHeaders(config.getAccessKeyId(), config.getAccessKeySecret()); + Map body= JgHelper.buildBody(phone, messages, templateId, config, code); + String jsonKey = JgHelper.buildJsonKey(config.getAction()); + try { + smsResponse = getResponse(http.postJson(url, headers, body), jsonKey); + } catch (SmsBlendException e) { + smsResponse = new SmsResponse(); + smsResponse.setSuccess(false); + smsResponse.setData(e.getMessage()); + } + + if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + retry = 0; + return smsResponse; + } + return requestRetry(phone, messages, templateId, code, msgId); + } + + private SmsResponse requestRetry(String phone, LinkedHashMap messages, + String templateId, String code, String msgId) { + http.safeSleep(getConfig().getRetryInterval()); + retry ++; + log.warn("短信第 {} 次重新发送", retry); + return getSmsResponse(phone, messages, templateId, code, msgId); + } + + private SmsResponse getResponse(JSONObject resJson, String jsonKey) { + SmsResponse smsResponse = new SmsResponse(); + smsResponse.setSuccess(resJson.getObj(jsonKey) != null); + smsResponse.setData(resJson); + smsResponse.setConfigId(getConfigId()); + return smsResponse; + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgHelper.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgHelper.java new file mode 100644 index 00000000..329e6f32 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgHelper.java @@ -0,0 +1,262 @@ +package org.dromara.sms4j.jg.util; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +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.SmsUtils; +import org.dromara.sms4j.jg.config.JgConfig; + +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

类名: JgHelper + *

说明:极光 sms + * + * @author :SmartFire + * 2024/3/15 + **/ +@Slf4j +public class JgHelper { + + /** + * 构造请求地址 + * @param baseUrl 配置的baseUrl + * @param action 请求方法 + * @param msgId 验证验证码是否有效时使用 msgId 为调用发送验证码 API 的返回值 + * @return url + */ + public static String buildUrl(String baseUrl, String action, String msgId) { + if ("valid".equals(action)){ + check(msgId); + return baseUrl + "codes/" + msgId + "/" + action; + }else { + return baseUrl + action; + } + } + + /** + * 构造请求头 + * @param accessKeyId appKey + * @param accessKeySecret appKey + * @return 请求头 + */ + public static Map buildHeaders(String accessKeyId, String accessKeySecret){ + check(accessKeyId); + check(accessKeySecret); + Map headers = new LinkedHashMap<>(3); + headers.put("Accept", Constant.ACCEPT); + headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); + headers.put("Authorization", "Basic " + Base64.encode(accessKeyId + ":" + accessKeySecret, StandardCharsets.UTF_8)); + return headers; + } + + /** + * 构造请求body + * @param phone 手机号 + * @param messages 消息体 + * @param templateId 模板 ID + * @param config 配置 + * @param code 验证码 + * @return 请求body + */ + public static Map buildBody(String phone, LinkedHashMap messages, + String templateId, JgConfig config, String code) { + checkAction(config.getAction()); + switch (config.getAction()){ + case "codes": + return buildBody(phone, config.getSignId(), templateId); + case "voice_codes": + return buildBody(phone, code, config.getVoice(), config.getTtl()); + case "valid": + return buildBody(code); + case "messages/batch": + return buildBody(phone, config.getSignId(), templateId, config.getTag(), messages); + default: + return buildBody(phone, config.getSignId(), templateId, messages); + } + } + + /** + * 构造返回json验证Key值 + * @param action 请求方法 + * @return 返回json验证Key值 + */ + public static String buildJsonKey(String action){ + checkAction(action); + switch (action){ + case "valid": + return "is_valid"; + case "messages/batch": + return "success_count"; + default: + return "msg_id"; + } + } + + /** + * 构造请求body 发送文本验证码短信 + * @param phone 手机号 + * @param signId 签名 ID,该字段为空则使用应用默认签名 + * @param templateId 模板 ID + * @return 请求body + */ + private static Map buildBody(String phone, String signId, String templateId) { + checkSingle(phone); + Map map = new LinkedHashMap<>(2); + map.put("mobile", phone); + check(templateId); + map.put("temp_id", templateId); + if (SmsUtils.isNotEmpty(signId)){ + map.put("sign_id", signId); + } + return map; + } + + /** + * 构造请求body 发送语音验证码短信 + * @param phone 手机号 + * @param code 语音验证码的值,验证码仅支持 4-8 个数字 可为空 + * @param voice 语音验证码播报语言选择,0:中文播报,1:英文播报,2:中英混合播报 + * @param ttl 验证码有效期,默认为 60 秒 + * @return 请求body + */ + private static Map buildBody(String phone, String code, String voice, Integer ttl) { + checkSingle(phone); + Map map = new LinkedHashMap<>(1); + map.put("mobile", phone); + if (SmsUtils.isNotEmpty(code)) { + map.put("code", code); + } + if (SmsUtils.isNotEmpty(voice)){ + checkVoice(voice); + map.put("voice_lang", voice); + } + if (ttl == null || ttl <= 0){ + map.put("ttl", 60); + }else { + map.put("ttl", ttl); + } + return map; + } + + /** + * 构造请求body 验证验证码是否有效 + * @param code 验证码 + * @return 请求body + */ + private static Map buildBody(String code) { + check(code); + Map map = new LinkedHashMap<>(1); + map.put("code", code); + return map; + } + + /** + * 构造请求body 发送单条模板短信 + * @param phone 手机号码 + * @param signId 签名 ID,该字段为空则使用应用默认签名 + * @param templateId 模板 ID + * @param messages 模板参数,需要替换的参数名和 value 的键值对 可为空 + * @return 请求body + */ + private static Map buildBody(String phone, String signId, String templateId, LinkedHashMap messages) { + checkSingle(phone); + Map map = new LinkedHashMap<>(1); + map.put("mobile", phone); + if (SmsUtils.isNotEmpty(signId)){ + map.put("sign_id", signId); + } + check(templateId); + map.put("temp_id", templateId); + checkMessages(messages); + map.put("temp_para", messages); + return map; + } + + /** + * 构造请求body 发送批量模板短信 + * @param phone 手机号码列表 + * @param signId 签名 ID,该字段为空则使用应用默认签名 + * @param templateId 模板 ID + * @param tag 标签 可为空 + * @param messages 模板参数,需要替换的参数名和 value 的键值对 + * @return 请求body + */ + private static Map buildBody(String phone, String signId, String templateId, + String tag, LinkedHashMap messages) { + Set phones = build(phone); + Map map = new LinkedHashMap<>(1); + if (SmsUtils.isNotEmpty(signId)){ + map.put("sign_id", signId); + } + if (SmsUtils.isNotEmpty(tag)){ + map.put("tag", tag); + } + if (SmsUtils.isEmpty(templateId)){ + log.error("templateId is required"); + throw new SmsBlendException("templateId is required"); + } + map.put("temp_id", templateId); + if (SmsUtils.isEmpty(messages)){ + log.error("temp_para is required"); + throw new SmsBlendException("temp_para is required"); + } + List> recipients = new ArrayList<>(phones.size()); + phones.forEach(mobile -> { + Map params = new LinkedHashMap<>(1); + params.put("temp_para", messages); + recipients.add(params); + }); + map.put("recipients", recipients); + return map; + } + + private static Set build(String phone){ + check(phone); + return Arrays.stream(phone.split(",")) + .filter(SmsUtils::isNotEmpty) + .map(String::trim) + .collect(Collectors.toSet()); + } + + private static void checkSingle(String phone){ + Set phones = build(phone); + if (phones.size() > 1) { + log.error("Only a single mobile number is supported"); + throw new SmsBlendException("Only a single mobile number is supported"); + } + } + + private static void checkMessages(LinkedHashMap messages){ + if (SmsUtils.isEmpty(messages)){ + log.error("temp_para is required"); + throw new SmsBlendException("temp_para is required"); + } + } + + private static void checkVoice(String voice){ + if (!StrUtil.equalsAny(voice, "0", "1", "2")){ + log.error("voice_lang is error, the value of an is only [1,2,3]"); + throw new SmsBlendException("voice_lang is error, the value of an is only [1,2,3]"); + } + } + + private static void checkAction(String action){ + if (SmsUtils.isEmpty(action) || !StrUtil.equalsAny(action, "codes", "voice_codes", "valid", "messages", "messages/batch")){ + log.error("Unknown action method"); + throw new SmsBlendException("Unknown action method"); + } + } + + private static void check(String str){ + if (SmsUtils.isEmpty(str)){ + String error = str + " is required"; + log.error(error); + throw new SmsBlendException(error); + } + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/config/JiguangConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/config/JiguangConfig.java deleted file mode 100644 index 64afca70..00000000 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/config/JiguangConfig.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.dromara.sms4j.jiguang.config; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.dromara.sms4j.comm.constant.SupplierConstant; -import org.dromara.sms4j.provider.config.BaseConfig; - -/** - *

类名: JiguangConfig - *

说明:极光 sms - * - * @author :SmartFire - * 2024/3/15 - **/ -@Data -@EqualsAndHashCode(callSuper = true) -public class JiguangConfig extends BaseConfig { - /** - * appKey - */ - private String appKey; - /** - * masterSecret - */ - private String masterSecret; - /** - * signid - */ - private String signId; - /** - * requestUrl - */ - private String requestUrl = "https://api.sms.jpush.cn/v1"; - /** - * 发送文本验证码短信 API - * curl --insecure -X POST -v https://api.sms.jpush.cn/v1/codes -H "Content-Type: application/json" \ - * -u "7d431e42dfa6a6d693ac2d04:5e987ac6d2e04d95a9d8f0d1" -d '{"mobile":"xxxxxxxxxxx","sign_id":*,"temp_id":*}' - */ - private String codeAction = "codes"; - /** - * 发送单条模板短信 API - * curl --insecure -X POST -v https://api.sms.jpush.cn/v1/messages -H "Content-Type: application/json" -u "7d431e42dfa6a6d693ac2d04:5e987ac6d2e04d95a9d8f0d1" \ - * -d '{"mobile":"xxxxxxxxxxxxxx","sign_id":*,"temp_id":1,"temp_para":{"xxxx":"xxxx"}}' - */ - private String singleTemplateAction = "messages"; - /** - * 发送批量模板短信 API - * curl --insecure -X POST -v https://api.sms.jpush.cn/v1/messages/batch -H "Content-Type: application/json" -u "7d431e42dfa6a6d693ac2d04:5e987ac6d2e04d95a9d8f0d1" -d \ - * '{ - * "sign_id": *, - * "temp_id": 1250, - * "tag":"标签", - * "recipients": [ - * { - * "mobile": "13812345678", - * "temp_para": { - * "number": "741627" - * } - * }, - * { - * "mobile": "18603050709", - * "temp_para": { - * "number": "147721" - * } - * } - * ] - * }' - */ - private String batchTemplateAction = "messages/batch"; - /** - * 获取供应商 - * - * @since 3.0.0 - */ - @Override - public String getSupplier() { - return SupplierConstant.JIGUANG; - } -} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/service/JiguangSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/service/JiguangSmsImpl.java deleted file mode 100644 index d4b4f9a1..00000000 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/service/JiguangSmsImpl.java +++ /dev/null @@ -1,192 +0,0 @@ -package org.dromara.sms4j.jiguang.service; - -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.codec.Base64; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; -import com.jdcloud.sdk.service.sms.model.BatchSendResult; -import lombok.extern.slf4j.Slf4j; -import org.dromara.sms4j.api.entity.SmsResponse; -import org.dromara.sms4j.comm.constant.SupplierConstant; -import org.dromara.sms4j.comm.delayedTime.DelayedTime; -import org.dromara.sms4j.jiguang.config.JiguangConfig; -import org.dromara.sms4j.jiguang.util.JiGuangHelper; -import org.dromara.sms4j.provider.service.AbstractSmsBlend; - -import java.util.*; -import java.util.concurrent.Executor; - -/** - *

类名: JiguangSmsImpl - *

说明:极光 sms - * - * @author :SmartFire - * 2024/3/15 - **/ -@Slf4j -public class JiguangSmsImpl extends AbstractSmsBlend { - - private JiguangConfig config; - private int retry = 0; - - - public JiguangSmsImpl(JiguangConfig config, Executor pool, DelayedTime delayed) { - super(config, pool, delayed); - this.config = getConfig(); - } - - public JiguangSmsImpl(JiguangConfig config) { - super(config); - this.config = getConfig(); - } - - @Override - public String getSupplier() { - return SupplierConstant.JIGUANG; - } - - @Override - public SmsResponse sendMessage(String phone, String message) { - SmsResponse response; - JiGuangHelper helper = new JiGuangHelper(getConfig(), http); - String url = String.format("%s/%s", config.getRequestUrl(), config.getCodeAction()); - String authCode = this.getBasicAuthorization(config.getAppKey(),config.getMasterSecret()); - //{"mobile":"xxxxxxxxxxx","sign_id":*,"temp_id":*} - Map map= new HashMap<>(); - map.put("mobile", phone); - map.put("temp_id", config.getTemplateId()); - map.put("sign_id", config.getSignId()); - - String json = JSONUtil.toJsonStr(map); - response = helper.smsResponse(json, url, authCode, "msg_id"); - return response; - } - - @Override - public SmsResponse sendMessage(String phone, LinkedHashMap messages) { - if (Objects.isNull(messages)){ - messages = new LinkedHashMap(); - } - SmsResponse response; - JiGuangHelper helper = new JiGuangHelper(getConfig(), http); - String url = String.format("%s/%s", config.getRequestUrl(), config.getSingleTemplateAction()); - String authCode = this.getBasicAuthorization(config.getAppKey(),config.getMasterSecret()); - //{"mobile":"xxxxxxxxxxxxxx","sign_id":*,"temp_id":1,"temp_para":{"xxxx":"xxxx"}} - - JSONObject temp_para = new JSONObject(); - Optional codekey = messages.keySet().stream().findFirst(); - - LinkedHashMap finalMessages = messages; - codekey.ifPresent(key -> { - temp_para.put(key, finalMessages.get(key)); - }); - - Map map= new HashMap<>(); - map.put("mobile", phone); - map.put("temp_id", config.getTemplateId()); - map.put("sign_id", config.getSignId()); - map.put("temp_para", temp_para); - - String json = JSONUtil.toJsonStr(map); - response = helper.smsResponse(json, url, authCode, "msg_id"); - return response; - } - - @Override - public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { - SmsResponse response; - JiGuangHelper helper = new JiGuangHelper(getConfig(), http); - String url = String.format("%s/%s", config.getRequestUrl(), config.getSingleTemplateAction()); - String authCode = this.getBasicAuthorization(config.getAppKey(),config.getMasterSecret()); - //{"mobile":"xxxxxxxxxxxxxx","sign_id":*,"temp_id":1,"temp_para":{"xxxx":"xxxx","xxxx":"xxxx"}} - - JSONObject temp_para = new JSONObject(); - - for (Map.Entry entry : messages.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - temp_para.put(key, value); - System.out.println(key + ": " + value); - } - - Map map= new HashMap<>(); - map.put("mobile", phone); - map.put("temp_id", templateId); - map.put("sign_id", config.getSignId()); - map.put("temp_para", temp_para); - - String json = JSONUtil.toJsonStr(map); - response = helper.smsResponse(json, url, authCode, "msg_id"); - return response; - } - - @Override - public SmsResponse massTexting(List phones, String message) { - LinkedHashMap map = new LinkedHashMap<>(); - map.put(IdUtil.fastSimpleUUID(), message); - return massTexting(phones, getConfig().getTemplateId(), map); - } - - @Override - public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages){ - SmsResponse response; - JiGuangHelper helper = new JiGuangHelper(getConfig(), http); - String url = String.format("%s/%s", config.getRequestUrl(), config.getBatchTemplateAction()); - String authCode = this.getBasicAuthorization(config.getAppKey(),config.getMasterSecret()); - - List recipients = new ArrayList(); - JSONObject temp_para; - JSONObject recipient; - for (String phone : phones) { - temp_para = new JSONObject(); - recipient = new JSONObject(); - recipient.put("mobile", phone); - for (Map.Entry entry : messages.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - temp_para.put(key, value); - System.out.println(key + ": " + value); - } - recipient.put("temp_para", temp_para); - recipients.add(recipient); - } - - Map map= new HashMap<>(); - map.put("temp_id", templateId); - map.put("sign_id", config.getSignId()); - map.put("tag", "标签"); - map.put("recipients", recipients); - - String json = JSONUtil.toJsonStr(map); - response = helper.smsResponse(json, url, authCode, "success_count"); - return response; - } - - - - private SmsResponse requestRetry(List phones, String templateId, LinkedHashMap messages) { - http.safeSleep(getConfig().getRetryInterval()); - retry++; - log.warn("短信第 {" + retry + "} 次重新发送"); - return massTexting(phones, templateId, messages); - } - - /** - * 获取短信返回信息 - * - * @param res 云商原始响应信息 - * @return 发送短信返回信息 - */ - private SmsResponse getSmsResponse(BatchSendResult res) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(res.getStatus() != null && res.getStatus()); - smsResponse.setData(res); - smsResponse.setConfigId(getConfigId()); - return smsResponse; - } - - private String getBasicAuthorization(String username, String password) { - String encodeKey = username + ":" + password; - return "Basic " + String.valueOf(Base64.encode(encodeKey)); - } -} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/util/JiGuangHelper.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/util/JiGuangHelper.java deleted file mode 100644 index c39c26b2..00000000 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jiguang/util/JiGuangHelper.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.dromara.sms4j.jiguang.util; - -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.json.JSONObject; -import lombok.extern.slf4j.Slf4j; -import org.dromara.sms4j.api.entity.SmsResponse; -import org.dromara.sms4j.comm.constant.Constant; -import org.dromara.sms4j.comm.exception.SmsBlendException; -import org.dromara.sms4j.comm.utils.SmsHttpUtils; -import org.dromara.sms4j.jiguang.config.JiguangConfig; - -import java.util.Map; - -/** - *

类名: JiGuangHelper - *

说明:极光 sms - * - * @author :SmartFire - * 2024/3/15 - **/ -@Slf4j -public class JiGuangHelper { - - private final JiguangConfig config; - private final SmsHttpUtils http; - private int retry = 0; - - public JiGuangHelper(JiguangConfig config, SmsHttpUtils http) { - this.config = config; - this.http = http; - } - - public SmsResponse smsResponse(String jsonMessage, String url, String authCode, String jsonKey) { - Map headers = MapUtil.newHashMap(2, true); - headers.put("Accept", Constant.ACCEPT); - headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); - headers.put("Authorization", authCode); - SmsResponse smsResponse = null; - try { - smsResponse = getResponse(http.postJson(url, headers, jsonMessage), jsonKey); - } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); - } - if (smsResponse.isSuccess() || retry == config.getMaxRetries()) { - retry = 0; - return smsResponse; - } - return requestRetry(jsonMessage, url, authCode, jsonKey); - - } - - private SmsResponse requestRetry(String jsonMessage, String url, String authCode, String jsonKey) { - http.safeSleep(config.getRetryInterval()); - retry++; - log.warn("短信第 {} 次重新发送", retry); - return smsResponse(jsonMessage, url, authCode, jsonKey); - } - - private SmsResponse getResponse(JSONObject resJson, String jsonKey ) { - SmsResponse smsResponse = new SmsResponse(); - String value = resJson.getStr(jsonKey); - if (StrUtil.isNotEmpty(value)) { - smsResponse.setSuccess(true); - } - smsResponse.setData(resJson); - smsResponse.setConfigId(this.config.getConfigId()); - return smsResponse; - } -} 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 79d2d474..ddf0d023 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 @@ -14,11 +14,9 @@ import org.dromara.sms4j.provider.service.AbstractSmsBlend; import org.dromara.sms4j.tencent.config.TencentConfig; import org.dromara.sms4j.tencent.utils.TencentUtils; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.Executor; /** @@ -44,12 +42,7 @@ public class TencentSmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { - String[] split = message.split("&"); - LinkedHashMap map = new LinkedHashMap<>(); - for (int i = 0; i < split.length; i++) { - map.put(String.valueOf(i), split[i]); - } - return sendMessage(phone, getConfig().getTemplateId(), map); + return sendMessage(phone, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); } @Override @@ -59,38 +52,17 @@ public class TencentSmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { - if (Objects.isNull(messages)){ - messages = new LinkedHashMap<>(); - } - List list = new ArrayList<>(); - for (Map.Entry entry : messages.entrySet()) { - list.add(entry.getValue()); - } - String[] s = new String[list.size()]; - return getSmsResponse(new String[]{StrUtil.addPrefixIfNot(phone, "+86")}, list.toArray(s), templateId); + return getSmsResponse(new String[]{StrUtil.addPrefixIfNot(phone, "+86")}, SmsUtils.toArray(messages.values(), SmsUtils::isNotEmpty, new String[0]), templateId); } @Override public SmsResponse massTexting(List phones, String message) { - String[] split = message.split("&"); - LinkedHashMap map = new LinkedHashMap<>(); - for (int i = 0; i < split.length; i++) { - map.put(String.valueOf(i), split[i]); - } - return massTexting(phones, getConfig().getTemplateId(), map); + return massTexting(phones, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); } @Override public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { - if (Objects.isNull(messages)){ - messages = new LinkedHashMap<>(); - } - List list = new ArrayList<>(); - for (Map.Entry entry : messages.entrySet()) { - list.add(entry.getValue()); - } - String[] s = new String[list.size()]; - return getSmsResponse(SmsUtils.listToArray(phones), list.toArray(s), templateId); + return getSmsResponse(SmsUtils.listToArray(phones), SmsUtils.toArray(messages.values(), SmsUtils::isNotEmpty, new String[0]), templateId); } private SmsResponse getSmsResponse(String[] phones, String[] messages, String templateId) { diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java index 354ae953..16546e44 100644 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java @@ -27,7 +27,7 @@ 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.chuanglan.config.ChuangLanFactory; -import org.dromara.sms4j.jiguang.config.JiguangFactory; +import org.dromara.sms4j.jg.config.JgFactory; import org.dromara.sms4j.lianlu.config.LianLuFactory; import org.dromara.sms4j.mas.config.MasFactory; import org.dromara.sms4j.netease.config.NeteaseFactory; @@ -125,7 +125,7 @@ public class SmsBlendsInitializer { ProviderFactoryHolder.registerFactory(ZhutongFactory.instance()); ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); ProviderFactoryHolder.registerFactory(ChuangLanFactory.instance()); - ProviderFactoryHolder.registerFactory(JiguangFactory.instance()); + ProviderFactoryHolder.registerFactory(JgFactory.instance()); ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); ProviderFactoryHolder.registerFactory(QiNiuFactory.instance()); ProviderFactoryHolder.registerFactory(BudingV2Factory.instance()); diff --git a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java index 661fa843..551edfaf 100644 --- a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java +++ b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java @@ -368,14 +368,14 @@ class Sms4jTest { } //测试群发【模板】 - List arrayList1 = new ArrayList<>(); + List arrayList = new ArrayList<>(); arrayList.add(PHONE); arrayList.add("135****000"); LinkedHashMap map = new LinkedHashMap<>(); map.put("1", "1544"); map.put("2", "2222"); SmsResponse smsResponse2 = SmsFactory.getBySupplier(SupplierConstant.CHUANGLAN).massTexting(arrayList, "[test]你的验证码是{$val},{$val}", map); - log.info("smsResponse:{}", smsResponse); + log.info("smsResponse2:{}", smsResponse2); //测试单条发送 SmsResponse smsResponse1 = SmsFactory.getBySupplier(SupplierConstant.CHUANGLAN).sendMessage(PHONE, "1544&2222"); @@ -385,41 +385,41 @@ class Sms4jTest { LinkedHashMap map3 = new LinkedHashMap<>(); map3.put("1", "1544"); map3.put("2", "2222"); - SmsResponse smsResponse3 = SmsFactory.getBySupplier(SupplierConstant.CHUANGLAN).sendMessage(PHONE, "[test]你的验证码是{$val},{$val}", map); - log.info("smsResponse2:{}", smsResponse2); + SmsResponse smsResponse3 = SmsFactory.getBySupplier(SupplierConstant.CHUANGLAN).sendMessage(PHONE, "[test]你的验证码是{$val},{$val}", map3); + log.info("smsResponse3:{}", smsResponse3); } /** * 极光短信 */ @Test - public void jiguangSmsTest_SendSMSCode() { - // 极光 发送文本验证码短信 API 不需要传入具体验证码,如果想传入自定义验证码,可通过模板短信方法,这里message为空即可 - SmsResponse smsResponse = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, "111"); - Assert.isTrue(smsResponse.isSuccess()); + public void jgSmsTest() { + // 极光 发送文本验证码短信 API 不需要传入具体验证码 返回 {"msg_id": "288193860302"} + SmsResponse smsResponse1 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, ""); + Assert.isTrue(smsResponse1.isSuccess()); // 极光 发送单条模板短信 API 发送自定义验证码 sendTemplateSMS - LinkedHashMap map = new LinkedHashMap<>(); - map.put("code", "123456"); - SmsResponse smsResponse = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, map); - Assert.isTrue(smsResponse.isSuccess()); + LinkedHashMap map1 = new LinkedHashMap<>(); + map1.put("code", "123456"); + SmsResponse smsResponse2 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, map1); + Assert.isTrue(smsResponse2.isSuccess()); // 极光 发送单条模板短信 API 发送多参数自定义模板短信 sendTemplateSMS_with_multipleParameters - LinkedHashMap map = new LinkedHashMap<>(); - map.put("name", "test"); - map.put("password", "test"); - SmsResponse smsResponse = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, "226992", map); - Assert.isTrue(smsResponse.isSuccess()); + LinkedHashMap map2 = new LinkedHashMap<>(); + map2.put("name", "test"); + map2.put("password", "test"); + SmsResponse smsResponse3 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, "226992", map2); + Assert.isTrue(smsResponse3.isSuccess()); // sendBatchTemplateSMS - LinkedHashMap map = new LinkedHashMap<>(); - map.put("name", "test"); - map.put("password", "test"); + LinkedHashMap map3 = new LinkedHashMap<>(); + map3.put("name", "test"); + map3.put("password", "test"); List phones = new ArrayList<>(); phones.add(PHONE); phones.add("xxx"); - SmsResponse smsResponse = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).massTexting(phones, "226992", map); - Assert.isTrue(smsResponse.isSuccess()); + SmsResponse smsResponse4 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).massTexting(phones, "226992", map3); + Assert.isTrue(smsResponse4.isSuccess()); } } \ No newline at end of file diff --git a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java index b177b787..8e15d804 100644 --- a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java +++ b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java @@ -29,7 +29,7 @@ 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.chuanglan.config.ChuangLanFactory; -import org.dromara.sms4j.jiguang.config.JiguangFactory; +import org.dromara.sms4j.jg.config.JgFactory; import org.dromara.sms4j.lianlu.config.LianLuFactory; import org.dromara.sms4j.mas.config.MasFactory; import org.dromara.sms4j.netease.config.NeteaseFactory; @@ -142,7 +142,7 @@ public class SmsBlendsInitializer { ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); ProviderFactoryHolder.registerFactory(QiNiuFactory.instance()); ProviderFactoryHolder.registerFactory(ChuangLanFactory.instance()); - ProviderFactoryHolder.registerFactory(JiguangFactory.instance()); + ProviderFactoryHolder.registerFactory(JgFactory.instance()); ProviderFactoryHolder.registerFactory(BudingV2Factory.instance()); ProviderFactoryHolder.registerFactory(MasFactory.instance()); ProviderFactoryHolder.registerFactory(BaiduFactory.instance());