Compare commits

..

No commits in common. "main" and "v0.1.0" have entirely different histories.
main ... v0.1.0

84 changed files with 522 additions and 3904 deletions

View File

@ -1,66 +0,0 @@
# 消息通知组件
## 如何使用
`com.simaek.notify.NotifyConfigManager`
实现getNotifyConfig(NotifyType notifyType, String id),从数据库或者配置文件读取通知器配置
`com.simaek.notify.template.AbstractTemplateManager`
实现方法getProperties(NotifyType notifyType, String id),从数据库或者配置文件读取模板配置
`com.simaek.notify.AbstractNotifierManager`
默认实现所有的方法,直接继承,有需要再覆写。
## 消息发送
需要实现或者覆写的功能全都完成了,直接使用即可,有两种发送方式。
1、使用预配置的模板发送信息适用于定时提醒、验证码等较为常用的信息
需要提供两个参数notifierIdtemplateId。
```
// 通过配置信息的ID和通知类型获取通知器
Notifier<Template> notifier = notifierManager.getNotifier(DefaultNotifyType.email, notifierId);
// 通过模板管理器获取模板
Template template = templateManager.getTemplate(DefaultNotifyType.email, templateId);
// 指定使用的消息模板和上下文,上下文用于对模板中的形如${name}的变量进行提换
notifier.send(template, new HashMap<>());
```
2、使用自定义模板发送信息适用于自定义消息以短信为例。
需要提供一个参数notifierId。
```
// 创建短信模板
TelecomSmsTemplate smsTemplate = new TelecomSmsTemplate();
smsTemplate.setMobile("18605120786,13047986669");
smsTemplate.setContent("你好,您的验证码是:${code}验证码有效期5分钟。");
// 创建模板配置文件
TemplateProperties templateProperties = new TemplateProperties();
// 定义模板类型为短信
templateProperties.setType(DefaultNotifyType.sms.getId());
// 选择短信服务提供商
templateProperties.setProvider(SmsProvider.js139.getId());
// 配置文件为了兼容不同模板是使用JSON字符串进行存储的需要转换一下
templateProperties.setTemplate(JSON.toJSONString(smsTemplate));
// 使用通知管理器创建模板,这一步会对模板进行渲染
Template template = templateManager.createTemplate(DefaultNotifyType.sms, templateProperties);
Map<String, Object> context = new HashMap<>();
context.put("code", "123456");
// 获取短信通知器并发送信息
Notifier<Template> notifier = notifierManager.getNotifier(DefaultNotifyType.sms, notifierId);
notifier.send(template, context);
```
## 其他
目前对接的通知服务有钉钉、微信公众号、企业微信、阿里云短信、云信通短信、电子邮件。如果想实现自己的通知器实现core模块中的接口即可。

View File

@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>notify-parent</artifactId> <artifactId>notify</artifactId>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<version>0.1.1</version> <version>0.1.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -21,16 +21,20 @@
<dependency> <dependency>
<groupId>commons-beanutils</groupId> <groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId> <artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-codec</groupId> <groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId> <artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId> <artifactId>spring-expression</artifactId>
<version>5.2.15.RELEASE</version>
<scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,6 +1,6 @@
package com.simaek.notify; package com.cicdi.notify;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;

View File

@ -1,4 +1,4 @@
package com.simaek.notify; package com.cicdi.notify;
/** /**
* 默认支持的通知类型 * 默认支持的通知类型

View File

@ -1,6 +1,6 @@
package com.simaek.notify; package com.cicdi.notify;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import java.util.Map; import java.util.Map;

View File

@ -1,6 +1,6 @@
package com.simaek.notify; package com.cicdi.notify;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
/** /**
* 通知器管理器用于获取获取通知器 * 通知器管理器用于获取获取通知器

View File

@ -1,4 +1,4 @@
package com.simaek.notify; package com.cicdi.notify;
import java.io.Serializable; import java.io.Serializable;
import java.util.Map; import java.util.Map;

View File

@ -1,6 +1,6 @@
package com.simaek.notify; package com.cicdi.notify;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
/** /**
* 通知服务商 * 通知服务商

View File

@ -1,4 +1,4 @@
package com.simaek.notify; package com.cicdi.notify;
/** /**
* 通知配置属性管理器用于统一管理通知配置属性 * 通知配置属性管理器用于统一管理通知配置属性

View File

@ -1,4 +1,4 @@
package com.simaek.notify; package com.cicdi.notify;
/** /**
* 通知类型通常使用枚举实现枚举支持的通知类型 * 通知类型通常使用枚举实现枚举支持的通知类型

View File

@ -1,4 +1,4 @@
package com.simaek.notify; package com.cicdi.notify;
/** /**
* 服务商标识通常使用枚举实现枚举支持的服务商 * 服务商标识通常使用枚举实现枚举支持的服务商

View File

@ -1,7 +1,7 @@
package com.simaek.notify.template; package com.cicdi.notify.template;
import com.simaek.notify.DefaultNotifyType; import com.cicdi.notify.DefaultNotifyType;
import com.simaek.notify.NotifyType; import com.cicdi.notify.NotifyType;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;

View File

@ -1,6 +1,6 @@
package com.simaek.notify.template; package com.cicdi.notify.template;
import com.simaek.notify.NotifierProvider; import com.cicdi.notify.NotifierProvider;
import java.io.Serializable; import java.io.Serializable;

View File

@ -1,6 +1,6 @@
package com.simaek.notify.template; package com.cicdi.notify.template;
import com.simaek.notify.NotifyType; import com.cicdi.notify.NotifyType;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;

View File

@ -1,7 +1,7 @@
package com.simaek.notify.template; package com.cicdi.notify.template;
import com.simaek.notify.NotifierProvider; import com.cicdi.notify.NotifierProvider;
import com.simaek.notify.NotifyType; import com.cicdi.notify.NotifyType;
import java.io.Serializable; import java.io.Serializable;

View File

@ -1,8 +1,8 @@
package com.simaek.notify.template; package com.cicdi.notify.template;
import com.simaek.notify.DefaultNotifyType; import com.cicdi.notify.DefaultNotifyType;
import com.simaek.notify.NotifyType; import com.cicdi.notify.NotifyType;
import com.simaek.notify.Provider; import com.cicdi.notify.Provider;
/** /**
* 通知模板服务商 * 通知模板服务商

View File

@ -1,7 +1,7 @@
package com.simaek.notify.util; package com.cicdi.notify.util;
import com.simaek.notify.util.script.engine.DynamicScriptEngine; import com.cicdi.notify.util.script.engine.DynamicScriptEngine;
import com.simaek.notify.util.script.engine.spel.SpelParserEngine; import com.cicdi.notify.util.script.engine.spel.SpelParserEngine;
import org.apache.commons.beanutils.BeanUtilsBean2; import org.apache.commons.beanutils.BeanUtilsBean2;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.util; package com.cicdi.notify.util;
import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.beanutils.BeanUtilsBean;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.util.script.engine; package com.cicdi.notify.util.script.engine;
import java.util.Map; import java.util.Map;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.util.script.engine; package com.cicdi.notify.util.script.engine;
import javax.script.ScriptException; import javax.script.ScriptException;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.util.script.engine; package com.cicdi.notify.util.script.engine;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.util.script.engine; package com.cicdi.notify.util.script.engine;
public class ScriptContext { public class ScriptContext {
private final String id; private final String id;

View File

@ -1,8 +1,8 @@
package com.simaek.notify.util.script.engine.spel; package com.cicdi.notify.util.script.engine.spel;
import com.simaek.notify.util.script.engine.ExecuteResult; import com.cicdi.notify.util.script.engine.ExecuteResult;
import com.simaek.notify.util.script.engine.ListenerSupportEngine; import com.cicdi.notify.util.script.engine.ListenerSupportEngine;
import com.simaek.notify.util.script.engine.ScriptContext; import com.cicdi.notify.util.script.engine.ScriptContext;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser; import org.springframework.expression.ExpressionParser;

View File

@ -1,33 +0,0 @@
package com.simaek.notify.util;
/**
* @author Yaser Hsueh
*/
public abstract class StringUtils {
public static boolean isEmpty(Object str) {
return (str == null || "".equals(str));
}
public static boolean hasLength(CharSequence str) {
return (str != null && str.length() > 0);
}
public static boolean hasLength(String str) {
return (str != null && !str.isEmpty());
}
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((!Character.isWhitespace(str.charAt(i)))) {
return false;
}
}
return true;
}
}

View File

@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>notify-parent</artifactId> <artifactId>notify</artifactId>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<version>0.1.1</version> <version>0.1.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -19,8 +19,9 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<artifactId>notify-core</artifactId> <artifactId>notify-core</artifactId>
<version>0.1.0</version>
</dependency> </dependency>
<dependency> <dependency>
@ -29,8 +30,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>okhttp</artifactId> <artifactId>httpclient</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,7 +1,7 @@
package com.simaek.notify.dingtalk; package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;

View File

@ -0,0 +1,128 @@
package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cicdi.notify.DefaultNotifyType;
import com.cicdi.notify.Notifier;
import com.cicdi.notify.NotifyType;
import com.cicdi.notify.Provider;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URISyntaxException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
public class DingTalkNotifier implements Notifier<DingTalkMessageTemplate> {
private final AtomicReference<String> accessToken = new AtomicReference<>();
private long refreshTokenTime;
private final long tokenTimeOut = Duration.ofSeconds(7000).toMillis();
private static final String tokenApi = "https://oapi.dingtalk.com/gettoken";
private static final String notifyApi = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2";
private final DingTalkProperties properties;
private final String notifierId;
@Override
public String getNotifierId() {
return notifierId;
}
public DingTalkNotifier(String id, DingTalkProperties properties) {
this.properties = properties;
this.notifierId = id;
}
@Override
public NotifyType getType() {
return DefaultNotifyType.dingTalk;
}
@Override
public Provider getProvider() {
return DingTalkProvider.dingTalkMessage;
}
@Override
public void send(DingTalkMessageTemplate template, Map<String, Object> context) {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("access_token", getToken()));
try {
HttpPost httpPost = new HttpPost(new URIBuilder(notifyApi).setParameters(params).build());
String formInserter = template.createFormInserter(context);
StringEntity entity = new StringEntity(template.createFormInserter(context));
httpPost.setEntity(entity);
CloseableHttpResponse response = httpClient.execute(httpPost);
JSONObject responseJson = JSON.parseObject(EntityUtils.toString(response.getEntity()));
System.out.println(responseJson);
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
}
private void checkResult(String msg) {
if ("0".equals(msg)) {
// log.info("发送钉钉通知成功");
} else {
// log.warn("发送钉钉通知失败:{}", map);
// throw new BusinessException("发送钉钉通知失败:" + map.get("errmsg"), code);
}
}
private String getToken() {
if (System.currentTimeMillis() - refreshTokenTime > tokenTimeOut || accessToken.get() == null) {
return requestToken();
}
return accessToken.get();
}
private String requestToken() {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("appkey", properties.getAppKey()));
params.add(new BasicNameValuePair("appsecret", properties.getAppSecret()));
try {
HttpGet httpGet = new HttpGet(new URIBuilder(tokenApi).setParameters(params).build());
CloseableHttpResponse response = httpClient.execute(httpGet);
JSONObject responseJson = JSON.parseObject(EntityUtils.toString(response.getEntity()));
if (responseJson.containsKey("access_token")) {
String access_token = responseJson.get("access_token").toString();
refreshTokenTime = System.currentTimeMillis();
accessToken.set(access_token);
return access_token;
} else {
// throw new BusinessException("获取Token失败:" + map.get("errmsg"), String.valueOf(map.get("errcode")));
}
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void close() {
accessToken.set(null);
refreshTokenTime = 0;
}
}

View File

@ -1,9 +1,9 @@
package com.simaek.notify.dingtalk; package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.template.TemplateProvider; import com.cicdi.notify.template.TemplateProvider;
import java.util.Objects; import java.util.Objects;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.dingtalk; package com.cicdi.notify.dingtalk;
/** /**
* 钉钉通知属性 * 钉钉通知属性

View File

@ -1,6 +1,6 @@
package com.simaek.notify.dingtalk; package com.cicdi.notify.dingtalk;
import com.simaek.notify.Provider; import com.cicdi.notify.Provider;
/** /**
* 钉钉通知提供商 * 钉钉通知提供商

View File

@ -1,122 +0,0 @@
package com.simaek.notify.dingtalk;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.DefaultNotifyType;
import com.simaek.notify.Notifier;
import com.simaek.notify.NotifyType;
import com.simaek.notify.Provider;
import okhttp3.*;
import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
public class DingTalkNotifier implements Notifier<DingTalkMessageTemplate> {
private final AtomicReference<String> accessToken = new AtomicReference<>();
private long refreshTokenTime;
private final long tokenTimeOut = Duration.ofSeconds(7000).toMillis();
private static final String tokenApi = "https://oapi.dingtalk.com/gettoken";
private static final String notifyApi = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2";
private final DingTalkProperties properties;
private final String notifierId;
private final OkHttpClient httpClient;
@Override
public String getNotifierId() {
return notifierId;
}
public DingTalkNotifier(String id, DingTalkProperties properties) {
this.properties = properties;
this.notifierId = id;
this.httpClient = new OkHttpClient.Builder().build();
}
@Override
public NotifyType getType() {
return DefaultNotifyType.dingTalk;
}
@Override
public Provider getProvider() {
return DingTalkProvider.dingTalkMessage;
}
@Override
public void send(DingTalkMessageTemplate template, Map<String, Object> context) {
HttpUrl url = Objects.requireNonNull(HttpUrl.parse(notifyApi)).newBuilder()
.addQueryParameter("access_token", getToken())
.build();
String formInserter = template.createFormInserter(context);
RequestBody requestBody = RequestBody.create(formInserter, MediaType.get("application/json"));
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Call call = httpClient.newCall(request);
try {
Response response = call.execute();
checkResult(Objects.requireNonNull(response.body()).string());
} catch (IOException e) {
e.printStackTrace();
}
}
private void checkResult(String msg) {
JSONObject jsonObject = JSON.parseObject(msg);
int errorCode = jsonObject.getIntValue("errcode");
if (errorCode != 0) {
throw new RuntimeException("发送钉钉通知失败:" + jsonObject.get("errmsg"));
}
}
private String getToken() {
if (System.currentTimeMillis() - refreshTokenTime > tokenTimeOut || accessToken.get() == null) {
return requestToken();
}
return accessToken.get();
}
private String requestToken() {
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(tokenApi)).newBuilder();
urlBuilder.addQueryParameter("appkey", properties.getAppKey());
urlBuilder.addQueryParameter("appsecret", properties.getAppSecret());
Request request = new Request.Builder()
.url(urlBuilder.build())
.get()
.build();
Call call = httpClient.newCall(request);
try {
Response response = call.execute();
JSONObject responseJson = JSON.parseObject(Objects.requireNonNull(response.body()).string());
if (responseJson.containsKey("access_token")) {
String access_token = responseJson.get("access_token").toString();
refreshTokenTime = System.currentTimeMillis();
accessToken.set(access_token);
return access_token;
} else {
throw new RuntimeException("获取Token失败:" + responseJson.get("errmsg"));
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void close() {
accessToken.set(null);
refreshTokenTime = 0;
}
}

View File

@ -1,11 +1,11 @@
package com.simaek.notify.dingtalk; package com.cicdi.notify.dingtalk;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.template.AbstractTemplateManager; import com.cicdi.notify.template.AbstractTemplateManager;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateManager; import com.cicdi.notify.template.TemplateManager;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>notify-parent</artifactId> <artifactId>notify</artifactId>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<version>0.1.1</version> <version>0.1.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -19,8 +19,15 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<artifactId>notify-core</artifactId> <artifactId>notify-core</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.15.RELEASE</version>
</dependency> </dependency>
<dependency> <dependency>
@ -31,16 +38,24 @@
<dependency> <dependency>
<groupId>com.sun.mail</groupId> <groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId> <artifactId>jakarta.mail</artifactId>
<version>1.6.7</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>okhttp</artifactId> <artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.10.RELEASE</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jsoup</groupId> <groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId> <artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,6 +1,6 @@
package com.simaek.notify.email; package com.cicdi.notify.email;
import com.simaek.notify.Provider; import com.cicdi.notify.Provider;
/** /**
* 邮件通知提供商 * 邮件通知提供商

View File

@ -1,6 +1,6 @@
package com.simaek.notify.email; package com.cicdi.notify.email;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.email; package com.cicdi.notify.email;
import java.util.Map; import java.util.Map;

View File

@ -1,24 +1,25 @@
package com.simaek.notify.email.embedded; package com.cicdi.notify.email.embedded;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.email.EmailProvider; import com.cicdi.notify.email.EmailProvider;
import com.simaek.notify.email.EmailTemplate; import com.cicdi.notify.email.EmailTemplate;
import com.simaek.notify.email.EmailTemplateParsed; import com.cicdi.notify.email.EmailTemplateParsed;
import com.simaek.notify.email.embedded.mail.javamail.JavaMailSender; import com.cicdi.notify.util.ExpressionUtils;
import com.simaek.notify.email.embedded.mail.javamail.JavaMailSenderImpl; import org.apache.http.HttpHeaders;
import com.simaek.notify.email.embedded.mail.javamail.MimeMessageHelper; import org.apache.http.HttpResponse;
import com.simaek.notify.util.ExpressionUtils; import org.apache.http.client.HttpClient;
import com.simaek.notify.util.StringUtils; import org.apache.http.client.methods.HttpGet;
import okhttp3.Call; import org.apache.http.impl.client.HttpClientBuilder;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.InputStreamSource; import org.springframework.core.io.InputStreamSource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.StringUtils;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
@ -56,8 +57,6 @@ public class DefaultEmailNotifier implements Notifier<EmailTemplate> {
private final String notifierId; private final String notifierId;
private final OkHttpClient httpClient;
@Override @Override
public String getNotifierId() { public String getNotifierId() {
return notifierId; return notifierId;
@ -76,7 +75,6 @@ public class DefaultEmailNotifier implements Notifier<EmailTemplate> {
mailSender.setJavaMailProperties(emailProperties.createJavaMailProperties()); mailSender.setJavaMailProperties(emailProperties.createJavaMailProperties());
this.sender = emailProperties.getSender(); this.sender = emailProperties.getSender();
this.javaMailSender = mailSender; this.javaMailSender = mailSender;
this.httpClient = new OkHttpClient.Builder().build();
} }
@Override @Override
@ -126,15 +124,12 @@ public class DefaultEmailNotifier implements Notifier<EmailTemplate> {
protected InputStreamSource convertResource(String resource) { protected InputStreamSource convertResource(String resource) {
if (resource.startsWith("http://") || resource.startsWith("https://")) { if (resource.startsWith("http://") || resource.startsWith("https://")) {
Request request = new Request.Builder() HttpClient httpClient = HttpClientBuilder.create().build();
.url(resource) HttpGet httpGet = new HttpGet(resource);
.get() httpGet.setHeader(HttpHeaders.ACCEPT, "application/octet-stream");
.header("Accept", "application/octet-stream")
.build();
Call call = httpClient.newCall(request);
try { try {
Response response = call.execute(); HttpResponse response = httpClient.execute(httpGet);
InputStream inputStream = Objects.requireNonNull(response.body()).byteStream(); InputStream inputStream = response.getEntity().getContent();
new InputStreamResource(inputStream); new InputStreamResource(inputStream);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -1,11 +1,11 @@
package com.simaek.notify.email.embedded; package com.cicdi.notify.email.embedded;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.email.EmailProvider; import com.cicdi.notify.email.EmailProvider;
import com.simaek.notify.email.EmailTemplate; import com.cicdi.notify.email.EmailTemplate;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.template.TemplateProvider; import com.cicdi.notify.template.TemplateProvider;
public class DefaultEmailNotifierProvider implements NotifierProvider, TemplateProvider { public class DefaultEmailNotifierProvider implements NotifierProvider, TemplateProvider {

View File

@ -1,4 +1,4 @@
package com.simaek.notify.email.embedded; package com.cicdi.notify.email.embedded;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;

View File

@ -1,39 +0,0 @@
package com.simaek.notify.email.embedded.mail;
/**
* Exception thrown on failed authentication.
*
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
*/
public class MailAuthenticationException extends MailException {
/**
* Constructor for MailAuthenticationException.
*
* @param msg message
*/
public MailAuthenticationException(String msg) {
super(msg);
}
/**
* Constructor for MailAuthenticationException.
*
* @param msg the detail message
* @param cause the root cause from the mail API in use
*/
public MailAuthenticationException(String msg, Throwable cause) {
super(msg, cause);
}
/**
* Constructor for MailAuthenticationException.
*
* @param cause the root cause from the mail API in use
*/
public MailAuthenticationException(Throwable cause) {
super("Authentication failed", cause);
}
}

View File

@ -1,32 +0,0 @@
package com.simaek.notify.email.embedded.mail;
import org.springframework.core.NestedRuntimeException;
import org.springframework.lang.Nullable;
/**
* Base class for all mail exceptions.
*
* @author Dmitriy Kopylenko
*/
public abstract class MailException extends NestedRuntimeException {
/**
* Constructor for MailException.
*
* @param msg the detail message
*/
public MailException(String msg) {
super(msg);
}
/**
* Constructor for MailException.
*
* @param msg the detail message
* @param cause the root cause from the mail API in use
*/
public MailException(@Nullable String msg, @Nullable Throwable cause) {
super(msg, cause);
}
}

View File

@ -1,46 +0,0 @@
package com.simaek.notify.email.embedded.mail;
import com.simaek.notify.email.embedded.mail.javamail.MimeMessageHelper;
import java.util.Date;
/**
* This is a common interface for mail messages, allowing a user to set key
* values required in assembling a mail message, without needing to know if
* the underlying message is a simple text message or a more sophisticated
* MIME message.
*
* <p>Implemented by both SimpleMailMessage and MimeMessageHelper,
* to let message population code interact with a simple message or a
* MIME message through a common interface.
*
* @author Juergen Hoeller
* @see SimpleMailMessage
* @see MimeMessageHelper
* @since 1.1.5
*/
public interface MailMessage {
void setFrom(String from) throws MailParseException;
void setReplyTo(String replyTo) throws MailParseException;
void setTo(String to) throws MailParseException;
void setTo(String... to) throws MailParseException;
void setCc(String cc) throws MailParseException;
void setCc(String... cc) throws MailParseException;
void setBcc(String bcc) throws MailParseException;
void setBcc(String... bcc) throws MailParseException;
void setSentDate(Date sentDate) throws MailParseException;
void setSubject(String subject) throws MailParseException;
void setText(String text) throws MailParseException;
}

View File

@ -1,39 +0,0 @@
package com.simaek.notify.email.embedded.mail;
/**
* Exception thrown if illegal message properties are encountered.
*
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
*/
public class MailParseException extends MailException {
/**
* Constructor for MailParseException.
*
* @param msg the detail message
*/
public MailParseException(String msg) {
super(msg);
}
/**
* Constructor for MailParseException.
*
* @param msg the detail message
* @param cause the root cause from the mail API in use
*/
public MailParseException(String msg, Throwable cause) {
super(msg, cause);
}
/**
* Constructor for MailParseException.
*
* @param cause the root cause from the mail API in use
*/
public MailParseException(Throwable cause) {
super("Could not parse mail", cause);
}
}

View File

@ -1,35 +0,0 @@
package com.simaek.notify.email.embedded.mail;
/**
* Exception to be thrown by user code if a mail cannot be prepared properly,
* for example when a FreeMarker template cannot be rendered for the mail text.
*
* @author Juergen Hoeller
* @since 1.1
*/
public class MailPreparationException extends MailException {
/**
* Constructor for MailPreparationException.
*
* @param msg the detail message
*/
public MailPreparationException(String msg) {
super(msg);
}
/**
* Constructor for MailPreparationException.
*
* @param msg the detail message
* @param cause the root cause from the mail API in use
*/
public MailPreparationException(String msg, Throwable cause) {
super(msg, cause);
}
public MailPreparationException(Throwable cause) {
super("Could not prepare mail", cause);
}
}

View File

@ -1,184 +0,0 @@
package com.simaek.notify.email.embedded.mail;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Exception thrown when a mail sending error is encountered.
* Can register failed messages with their exceptions.
*
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
*/
public class MailSendException extends MailException {
private final transient Map<Object, Exception> failedMessages;
@Nullable
private final Exception[] messageExceptions;
/**
* Constructor for MailSendException.
*
* @param msg the detail message
*/
public MailSendException(String msg) {
this(msg, null);
}
/**
* Constructor for MailSendException.
*
* @param msg the detail message
* @param cause the root cause from the mail API in use
*/
public MailSendException(String msg, @Nullable Throwable cause) {
super(msg, cause);
this.failedMessages = new LinkedHashMap<>();
this.messageExceptions = null;
}
/**
* Constructor for registration of failed messages, with the
* messages that failed as keys, and the thrown exceptions as values.
* <p>The messages should be the same that were originally passed
* to the invoked send method.
*
* @param msg the detail message
* @param cause the root cause from the mail API in use
* @param failedMessages a Map of failed messages as keys and thrown
* exceptions as values
*/
public MailSendException(@Nullable String msg, @Nullable Throwable cause, Map<Object, Exception> failedMessages) {
super(msg, cause);
this.failedMessages = new LinkedHashMap<>(failedMessages);
this.messageExceptions = failedMessages.values().toArray(new Exception[0]);
}
/**
* Constructor for registration of failed messages, with the
* messages that failed as keys, and the thrown exceptions as values.
* <p>The messages should be the same that were originally passed
* to the invoked send method.
*
* @param failedMessages a Map of failed messages as keys and thrown
* exceptions as values
*/
public MailSendException(Map<Object, Exception> failedMessages) {
this(null, null, failedMessages);
}
/**
* Return a Map with the failed messages as keys, and the thrown exceptions
* as values.
* <p>Note that a general mail server connection failure will not result
* in failed messages being returned here: A message will only be
* contained here if actually sending it was attempted but failed.
* <p>The messages will be the same that were originally passed to the
* invoked send method, that is, SimpleMailMessages in case of using
* the generic MailSender interface.
* <p>In case of sending MimeMessage instances via JavaMailSender,
* the messages will be of type MimeMessage.
* <p><b>NOTE:</b> This Map will not be available after serialization.
* Use {@link #getMessageExceptions()} in such a scenario, which will
* be available after serialization as well.
*
* @return the Map of failed messages as keys and thrown exceptions as values
* @see SimpleMailMessage
* @see javax.mail.internet.MimeMessage
*/
public final Map<Object, Exception> getFailedMessages() {
return this.failedMessages;
}
/**
* Return an array with thrown message exceptions.
* <p>Note that a general mail server connection failure will not result
* in failed messages being returned here: A message will only be
* contained here if actually sending it was attempted but failed.
*
* @return the array of thrown message exceptions,
* or an empty array if no failed messages
*/
public final Exception[] getMessageExceptions() {
return (this.messageExceptions != null ? this.messageExceptions : new Exception[0]);
}
@Override
@Nullable
public String getMessage() {
if (ObjectUtils.isEmpty(this.messageExceptions)) {
return super.getMessage();
} else {
StringBuilder sb = new StringBuilder();
String baseMessage = super.getMessage();
if (baseMessage != null) {
sb.append(baseMessage).append(". ");
}
sb.append("Failed messages: ");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
sb.append(subEx.toString());
if (i < this.messageExceptions.length - 1) {
sb.append("; ");
}
}
return sb.toString();
}
}
@Override
public String toString() {
if (ObjectUtils.isEmpty(this.messageExceptions)) {
return super.toString();
} else {
StringBuilder sb = new StringBuilder(super.toString());
sb.append("; message exceptions (").append(this.messageExceptions.length).append(") are:");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
sb.append('\n').append("Failed message ").append(i + 1).append(": ");
sb.append(subEx);
}
return sb.toString();
}
}
@Override
public void printStackTrace(PrintStream ps) {
if (ObjectUtils.isEmpty(this.messageExceptions)) {
super.printStackTrace(ps);
} else {
ps.println(super.toString() + "; message exception details (" +
this.messageExceptions.length + ") are:");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
ps.println("Failed message " + (i + 1) + ":");
subEx.printStackTrace(ps);
}
}
}
@Override
public void printStackTrace(PrintWriter pw) {
if (ObjectUtils.isEmpty(this.messageExceptions)) {
super.printStackTrace(pw);
} else {
pw.println(super.toString() + "; message exception details (" +
this.messageExceptions.length + ") are:");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
pw.println("Failed message " + (i + 1) + ":");
subEx.printStackTrace(pw);
}
}
}
}

View File

@ -1,40 +0,0 @@
package com.simaek.notify.email.embedded.mail;
import com.simaek.notify.email.embedded.mail.javamail.JavaMailSender;
/**
* This interface defines a strategy for sending simple mails. Can be
* implemented for a variety of mailing systems due to the simple requirements.
* For richer functionality like MIME messages, consider JavaMailSender.
*
* <p>Allows for easy testing of clients, as it does not depend on JavaMail's
* infrastructure classes: no mocking of JavaMail Session or Transport necessary.
*
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
* @see JavaMailSender
* @since 10.09.2003
*/
public interface MailSender {
/**
* Send the given simple mail message.
*
* @param simpleMessage the message to send
* @throws MailParseException in case of failure when parsing the message
* @throws MailAuthenticationException in case of authentication failure
* @throws MailSendException in case of failure when sending the message
*/
void send(SimpleMailMessage simpleMessage) throws MailException;
/**
* Send the given array of simple mail messages in batch.
*
* @param simpleMessages the messages to send
* @throws MailParseException in case of failure when parsing a message
* @throws MailAuthenticationException in case of authentication failure
* @throws MailSendException in case of failure when sending a message
*/
void send(SimpleMailMessage... simpleMessages) throws MailException;
}

View File

@ -1,270 +0,0 @@
package com.simaek.notify.email.embedded.mail;
import com.simaek.notify.email.embedded.mail.javamail.JavaMailSender;
import com.simaek.notify.email.embedded.mail.javamail.MimeMailMessage;
import com.simaek.notify.email.embedded.mail.javamail.MimeMessageHelper;
import com.simaek.notify.email.embedded.mail.javamail.MimeMessagePreparator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.Date;
/**
* Models a simple mail message, including data such as the from, to, cc, subject,
* and text fields.
*
* <p>Consider {@code JavaMailSender} and JavaMail {@code MimeMessages} for creating
* more sophisticated messages, for example messages with attachments, special
* character encodings, or personal names that accompany mail addresses.
*
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
* @see MailSender
* @see JavaMailSender
* @see MimeMessagePreparator
* @see MimeMessageHelper
* @see MimeMailMessage
* @since 10.09.2003
*/
public class SimpleMailMessage implements MailMessage, Serializable {
@Nullable
private String from;
@Nullable
private String replyTo;
@Nullable
private String[] to;
@Nullable
private String[] cc;
@Nullable
private String[] bcc;
@Nullable
private Date sentDate;
@Nullable
private String subject;
@Nullable
private String text;
/**
* Create a new {@code SimpleMailMessage}.
*/
public SimpleMailMessage() {
}
/**
* Copy constructor for creating a new {@code SimpleMailMessage} from the state
* of an existing {@code SimpleMailMessage} instance.
*/
public SimpleMailMessage(SimpleMailMessage original) {
Assert.notNull(original, "'original' message argument must not be null");
this.from = original.getFrom();
this.replyTo = original.getReplyTo();
this.to = copyOrNull(original.getTo());
this.cc = copyOrNull(original.getCc());
this.bcc = copyOrNull(original.getBcc());
this.sentDate = original.getSentDate();
this.subject = original.getSubject();
this.text = original.getText();
}
@Override
public void setFrom(String from) {
this.from = from;
}
@Nullable
public String getFrom() {
return this.from;
}
@Override
public void setReplyTo(String replyTo) {
this.replyTo = replyTo;
}
@Nullable
public String getReplyTo() {
return this.replyTo;
}
@Override
public void setTo(String to) {
this.to = new String[]{to};
}
@Override
public void setTo(String... to) {
this.to = to;
}
@Nullable
public String[] getTo() {
return this.to;
}
@Override
public void setCc(String cc) {
this.cc = new String[]{cc};
}
@Override
public void setCc(String... cc) {
this.cc = cc;
}
@Nullable
public String[] getCc() {
return this.cc;
}
@Override
public void setBcc(String bcc) {
this.bcc = new String[]{bcc};
}
@Override
public void setBcc(String... bcc) {
this.bcc = bcc;
}
@Nullable
public String[] getBcc() {
return this.bcc;
}
@Override
public void setSentDate(Date sentDate) {
this.sentDate = sentDate;
}
@Nullable
public Date getSentDate() {
return this.sentDate;
}
@Override
public void setSubject(String subject) {
this.subject = subject;
}
@Nullable
public String getSubject() {
return this.subject;
}
@Override
public void setText(String text) {
this.text = text;
}
@Nullable
public String getText() {
return this.text;
}
/**
* Copy the contents of this message to the given target message.
*
* @param target the {@code MailMessage} to copy to
*/
public void copyTo(MailMessage target) {
Assert.notNull(target, "'target' MailMessage must not be null");
if (getFrom() != null) {
target.setFrom(getFrom());
}
if (getReplyTo() != null) {
target.setReplyTo(getReplyTo());
}
if (getTo() != null) {
target.setTo(copy(getTo()));
}
if (getCc() != null) {
target.setCc(copy(getCc()));
}
if (getBcc() != null) {
target.setBcc(copy(getBcc()));
}
if (getSentDate() != null) {
target.setSentDate(getSentDate());
}
if (getSubject() != null) {
target.setSubject(getSubject());
}
if (getText() != null) {
target.setText(getText());
}
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof SimpleMailMessage)) {
return false;
}
SimpleMailMessage otherMessage = (SimpleMailMessage) other;
return (ObjectUtils.nullSafeEquals(this.from, otherMessage.from) &&
ObjectUtils.nullSafeEquals(this.replyTo, otherMessage.replyTo) &&
ObjectUtils.nullSafeEquals(this.to, otherMessage.to) &&
ObjectUtils.nullSafeEquals(this.cc, otherMessage.cc) &&
ObjectUtils.nullSafeEquals(this.bcc, otherMessage.bcc) &&
ObjectUtils.nullSafeEquals(this.sentDate, otherMessage.sentDate) &&
ObjectUtils.nullSafeEquals(this.subject, otherMessage.subject) &&
ObjectUtils.nullSafeEquals(this.text, otherMessage.text));
}
@Override
public int hashCode() {
int hashCode = ObjectUtils.nullSafeHashCode(this.from);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.replyTo);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.to);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.cc);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.bcc);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.sentDate);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.subject);
return hashCode;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("SimpleMailMessage: ");
sb.append("from=").append(this.from).append("; ");
sb.append("replyTo=").append(this.replyTo).append("; ");
sb.append("to=").append(StringUtils.arrayToCommaDelimitedString(this.to)).append("; ");
sb.append("cc=").append(StringUtils.arrayToCommaDelimitedString(this.cc)).append("; ");
sb.append("bcc=").append(StringUtils.arrayToCommaDelimitedString(this.bcc)).append("; ");
sb.append("sentDate=").append(this.sentDate).append("; ");
sb.append("subject=").append(this.subject).append("; ");
sb.append("text=").append(this.text);
return sb.toString();
}
@Nullable
private static String[] copyOrNull(@Nullable String[] state) {
if (state == null) {
return null;
}
return copy(state);
}
private static String[] copy(String[] state) {
return state.clone();
}
}

View File

@ -1,159 +0,0 @@
package com.simaek.notify.email.embedded.mail.javamail;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* Spring-configurable {@code FileTypeMap} implementation that will read
* MIME type to file extension mappings from a standard JavaMail MIME type
* mapping file, using a standard {@code MimetypesFileTypeMap} underneath.
*
* <p>The mapping file should be in the following format, as specified by the
* Java Activation Framework:
*
* <pre class="code">
* # map text/html to .htm and .html files
* text/html html htm HTML HTM</pre>
* <p>
* Lines starting with {@code #} are treated as comments and are ignored. All
* other lines are treated as mappings. Each mapping line should contain the MIME
* type as the first entry and then each file extension to map to that MIME type
* as subsequent entries. Each entry is separated by spaces or tabs.
*
* <p>By default, the mappings in the {@code mime.types} file located in the
* same package as this class are used, which cover many common file extensions
* (in contrast to the out-of-the-box mappings in {@code activation.jar}).
* This can be overridden using the {@code mappingLocation} property.
*
* <p>Additional mappings can be added via the {@code mappings} bean property,
* as lines that follow the {@code mime.types} file format.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @see #setMappingLocation
* @see #setMappings
* @see MimetypesFileTypeMap
* @since 1.2
*/
public class ConfigurableMimeFileTypeMap extends FileTypeMap {
/**
* The {@code Resource} to load the mapping file from.
*/
private Resource mappingLocation = new ClassPathResource("mime.types", getClass());
/**
* Used to configure additional mappings.
*/
@Nullable
private String[] mappings;
/**
* The delegate FileTypeMap, compiled from the mappings in the mapping file
* and the entries in the {@code mappings} property.
*/
@Nullable
private FileTypeMap fileTypeMap;
/**
* Specify the {@code Resource} from which mappings are loaded.
* <p>Needs to follow the {@code mime.types} file format, as specified
* by the Java Activation Framework, containing lines such as:<br>
* {@code text/html html htm HTML HTM}
*/
public void setMappingLocation(Resource mappingLocation) {
this.mappingLocation = mappingLocation;
}
/**
* Specify additional MIME type mappings as lines that follow the
* {@code mime.types} file format, as specified by the
* Java Activation Framework. For example:<br>
* {@code text/html html htm HTML HTM}
*/
public void setMappings(String... mappings) {
this.mappings = mappings;
}
/**
* Return the delegate FileTypeMap, compiled from the mappings in the mapping file
* and the entries in the {@code mappings} property.
*
* @see #setMappingLocation
* @see #setMappings
* @see #createFileTypeMap
*/
protected final FileTypeMap getFileTypeMap() {
if (this.fileTypeMap == null) {
try {
this.fileTypeMap = createFileTypeMap(this.mappingLocation, this.mappings);
} catch (IOException ex) {
throw new IllegalStateException(
"Could not load specified MIME type mapping file: " + this.mappingLocation, ex);
}
}
return this.fileTypeMap;
}
/**
* Compile a {@link FileTypeMap} from the mappings in the given mapping file
* and the given mapping entries.
* <p>The default implementation creates an Activation Framework {@link MimetypesFileTypeMap},
* passing in an InputStream from the mapping resource (if any) and registering
* the mapping lines programmatically.
*
* @param mappingLocation a {@code mime.types} mapping resource (can be {@code null})
* @param mappings an array of MIME type mapping lines (can be {@code null})
* @return the compiled FileTypeMap
* @throws IOException if resource access failed
* @see MimetypesFileTypeMap#MimetypesFileTypeMap(InputStream)
* @see MimetypesFileTypeMap#addMimeTypes(String)
*/
protected FileTypeMap createFileTypeMap(@Nullable Resource mappingLocation, @Nullable String[] mappings) throws IOException {
MimetypesFileTypeMap fileTypeMap = null;
if (mappingLocation != null) {
try (InputStream is = mappingLocation.getInputStream()) {
fileTypeMap = new MimetypesFileTypeMap(is);
}
} else {
fileTypeMap = new MimetypesFileTypeMap();
}
if (mappings != null) {
for (String mapping : mappings) {
fileTypeMap.addMimeTypes(mapping);
}
}
return fileTypeMap;
}
/**
* Delegates to the underlying FileTypeMap.
*
* @see #getFileTypeMap()
*/
@Override
public String getContentType(File file) {
return getFileTypeMap().getContentType(file);
}
/**
* Delegates to the underlying FileTypeMap.
*
* @see #getFileTypeMap()
*/
@Override
public String getContentType(String fileName) {
return getFileTypeMap().getContentType(fileName);
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.simaek.notify.email.embedded.mail.javamail;
import org.springframework.util.StringUtils;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import java.beans.PropertyEditorSupport;
/**
* Editor for {@code java.mail.internet.InternetAddress},
* to directly populate an InternetAddress property.
*
* <p>Expects the same syntax as InternetAddress's constructor with
* a String argument. Converts empty Strings into null values.
*
* @author Juergen Hoeller
* @since 1.2.3
* @see InternetAddress
*/
public class InternetAddressEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
try {
setValue(new InternetAddress(text));
}
catch (AddressException ex) {
throw new IllegalArgumentException("Could not parse mail address: " + ex.getMessage());
}
}
else {
setValue(null);
}
}
@Override
public String getAsText() {
InternetAddress value = (InternetAddress) getValue();
return (value != null ? value.toUnicodeString() : "");
}
}

View File

@ -1,118 +0,0 @@
package com.simaek.notify.email.embedded.mail.javamail;
import com.simaek.notify.email.embedded.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.InputStream;
/**
* Extended {@link MailSender} interface for JavaMail,
* supporting MIME messages both as direct arguments and through preparation
* callbacks. Typically used in conjunction with the {@link MimeMessageHelper}
* class for convenient creation of JavaMail {@link MimeMessage MimeMessages},
* including attachments etc.
*
* <p>Clients should talk to the mail sender through this interface if they need
* mail functionality beyond {@link SimpleMailMessage}.
* The production implementation is {@link JavaMailSenderImpl}; for testing,
* mocks can be created based on this interface. Clients will typically receive
* the JavaMailSender reference through dependency injection.
*
* <p>The recommended way of using this interface is the {@link MimeMessagePreparator}
* mechanism, possibly using a {@link MimeMessageHelper} for populating the message.
* See {@link MimeMessageHelper MimeMessageHelper's javadoc} for an example.
*
* <p>The entire JavaMail {@link javax.mail.Session} management is abstracted
* by the JavaMailSender. Client code should not deal with a Session in any way,
* rather leave the entire JavaMail configuration and resource handling to the
* JavaMailSender implementation. This also increases testability.
*
* <p>A JavaMailSender client is not as easy to test as a plain
* {@link MailSender} client, but still straightforward
* compared to traditional JavaMail code: Just let {@link #createMimeMessage()}
* return a plain {@link MimeMessage} created with a
* {@code Session.getInstance(new Properties())} call, and check the passed-in
* messages in your mock implementations of the various {@code send} methods.
*
* @author Juergen Hoeller
* @see MimeMessage
* @see javax.mail.Session
* @see JavaMailSenderImpl
* @see MimeMessagePreparator
* @see MimeMessageHelper
* @since 07.10.2003
*/
public interface JavaMailSender extends MailSender {
/**
* Create a new JavaMail MimeMessage for the underlying JavaMail Session
* of this sender. Needs to be called to create MimeMessage instances
* that can be prepared by the client and passed to send(MimeMessage).
*
* @return the new MimeMessage instance
* @see #send(MimeMessage)
* @see #send(MimeMessage[])
*/
MimeMessage createMimeMessage();
/**
* Create a new JavaMail MimeMessage for the underlying JavaMail Session
* of this sender, using the given input stream as the message source.
*
* @param contentStream the raw MIME input stream for the message
* @return the new MimeMessage instance
* @throws MailParseException in case of message creation failure
*/
MimeMessage createMimeMessage(InputStream contentStream) throws MailException;
/**
* Send the given JavaMail MIME message.
* The message needs to have been created with {@link #createMimeMessage()}.
*
* @param mimeMessage message to send
* @throws MailAuthenticationException in case of authentication failure
* @throws MailSendException in case of failure when sending the message
* @see #createMimeMessage
*/
void send(MimeMessage mimeMessage) throws MailException;
/**
* Send the given array of JavaMail MIME messages in batch.
* The messages need to have been created with {@link #createMimeMessage()}.
*
* @param mimeMessages messages to send
* @throws MailAuthenticationException in case of authentication failure
* @throws MailSendException in case of failure when sending a message
* @see #createMimeMessage
*/
void send(MimeMessage... mimeMessages) throws MailException;
/**
* Send the JavaMail MIME message prepared by the given MimeMessagePreparator.
* <p>Alternative way to prepare MimeMessage instances, instead of
* {@link #createMimeMessage()} and {@link #send(MimeMessage)} calls.
* Takes care of proper exception conversion.
*
* @param mimeMessagePreparator the preparator to use
* @throws MailPreparationException in case of failure when preparing the message
* @throws MailParseException in case of failure when parsing the message
* @throws MailAuthenticationException in case of authentication failure
* @throws MailSendException in case of failure when sending the message
*/
void send(MimeMessagePreparator mimeMessagePreparator) throws MailException;
/**
* Send the JavaMail MIME messages prepared by the given MimeMessagePreparators.
* <p>Alternative way to prepare MimeMessage instances, instead of
* {@link #createMimeMessage()} and {@link #send(MimeMessage[])} calls.
* Takes care of proper exception conversion.
*
* @param mimeMessagePreparators the preparator to use
* @throws MailPreparationException in case of failure when preparing a message
* @throws MailParseException in case of failure when parsing a message
* @throws MailAuthenticationException in case of authentication failure
* @throws MailSendException in case of failure when sending a message
*/
void send(MimeMessagePreparator... mimeMessagePreparators) throws MailException;
}

View File

@ -1,507 +0,0 @@
package com.simaek.notify.email.embedded.mail.javamail;
import com.simaek.notify.email.embedded.mail.*;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import javax.activation.FileTypeMap;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.InputStream;
import java.util.*;
/**
* Production implementation of the {@link JavaMailSender} interface,
* supporting both JavaMail {@link MimeMessage MimeMessages} and Spring
* {@link SimpleMailMessage SimpleMailMessages}. Can also be used as a
* plain {@link MailSender} implementation.
*
* <p>Allows for defining all settings locally as bean properties.
* Alternatively, a pre-configured JavaMail {@link Session} can be
* specified, possibly pulled from an application server's JNDI environment.
*
* <p>Non-default properties in this object will always override the settings
* in the JavaMail {@code Session}. Note that if overriding all values locally,
* there is no added value in setting a pre-configured {@code Session}.
*
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
* @see MimeMessage
* @see Session
* @see #setSession
* @see #setJavaMailProperties
* @see #setHost
* @see #setPort
* @see #setUsername
* @see #setPassword
* @since 10.09.2003
*/
public class JavaMailSenderImpl implements JavaMailSender {
/**
* The default protocol: 'smtp'.
*/
public static final String DEFAULT_PROTOCOL = "smtp";
/**
* The default port: -1.
*/
public static final int DEFAULT_PORT = -1;
private static final String HEADER_MESSAGE_ID = "Message-ID";
private Properties javaMailProperties = new Properties();
@Nullable
private Session session;
@Nullable
private String protocol;
@Nullable
private String host;
private int port = DEFAULT_PORT;
@Nullable
private String username;
@Nullable
private String password;
@Nullable
private String defaultEncoding;
@Nullable
private FileTypeMap defaultFileTypeMap;
/**
* Create a new instance of the {@code JavaMailSenderImpl} class.
* <p>Initializes the {@link #setDefaultFileTypeMap "defaultFileTypeMap"}
* property with a default {@link ConfigurableMimeFileTypeMap}.
*/
public JavaMailSenderImpl() {
ConfigurableMimeFileTypeMap fileTypeMap = new ConfigurableMimeFileTypeMap();
// fileTypeMap.afterPropertiesSet();
this.defaultFileTypeMap = fileTypeMap;
}
/**
* Set JavaMail properties for the {@code Session}.
* <p>A new {@code Session} will be created with those properties.
* Use either this method or {@link #setSession}, but not both.
* <p>Non-default properties in this instance will override given
* JavaMail properties.
*/
public void setJavaMailProperties(Properties javaMailProperties) {
this.javaMailProperties = javaMailProperties;
synchronized (this) {
this.session = null;
}
}
/**
* Allow {code Map} access to the JavaMail properties of this sender,
* with the option to add or override specific entries.
* <p>Useful for specifying entries directly, for example via
* {code javaMailProperties[mail.smtp.auth]}.
*/
public Properties getJavaMailProperties() {
return this.javaMailProperties;
}
/**
* Set the JavaMail {@code Session}, possibly pulled from JNDI.
* <p>Default is a new {@code Session} without defaults, that is
* completely configured via this instance's properties.
* <p>If using a pre-configured {@code Session}, non-default properties
* in this instance will override the settings in the {@code Session}.
*
* @see #setJavaMailProperties
*/
public synchronized void setSession(Session session) {
Assert.notNull(session, "Session must not be null");
this.session = session;
}
/**
* Return the JavaMail {@code Session},
* lazily initializing it if it hasn't been specified explicitly.
*/
public synchronized Session getSession() {
if (this.session == null) {
this.session = Session.getInstance(this.javaMailProperties);
}
return this.session;
}
/**
* Set the mail protocol. Default is "smtp".
*/
public void setProtocol(@Nullable String protocol) {
this.protocol = protocol;
}
/**
* Return the mail protocol.
*/
@Nullable
public String getProtocol() {
return this.protocol;
}
/**
* Set the mail server host, typically an SMTP host.
* <p>Default is the default host of the underlying JavaMail Session.
*/
public void setHost(@Nullable String host) {
this.host = host;
}
/**
* Return the mail server host.
*/
@Nullable
public String getHost() {
return this.host;
}
/**
* Set the mail server port.
* <p>Default is {@link #DEFAULT_PORT}, letting JavaMail use the default
* SMTP port (25).
*/
public void setPort(int port) {
this.port = port;
}
/**
* Return the mail server port.
*/
public int getPort() {
return this.port;
}
/**
* Set the username for the account at the mail host, if any.
* <p>Note that the underlying JavaMail {@code Session} has to be
* configured with the property {@code "mail.smtp.auth"} set to
* {@code true}, else the specified username will not be sent to the
* mail server by the JavaMail runtime. If you are not explicitly passing
* in a {@code Session} to use, simply specify this setting via
* {@link #setJavaMailProperties}.
*
* @see #setSession
* @see #setPassword
*/
public void setUsername(@Nullable String username) {
this.username = username;
}
/**
* Return the username for the account at the mail host.
*/
@Nullable
public String getUsername() {
return this.username;
}
/**
* Set the password for the account at the mail host, if any.
* <p>Note that the underlying JavaMail {@code Session} has to be
* configured with the property {@code "mail.smtp.auth"} set to
* {@code true}, else the specified password will not be sent to the
* mail server by the JavaMail runtime. If you are not explicitly passing
* in a {@code Session} to use, simply specify this setting via
* {@link #setJavaMailProperties}.
*
* @see #setSession
* @see #setUsername
*/
public void setPassword(@Nullable String password) {
this.password = password;
}
/**
* Return the password for the account at the mail host.
*/
@Nullable
public String getPassword() {
return this.password;
}
/**
* Set the default encoding to use for {@link MimeMessage MimeMessages}
* created by this instance.
* <p>Such an encoding will be auto-detected by {@link MimeMessageHelper}.
*/
public void setDefaultEncoding(@Nullable String defaultEncoding) {
this.defaultEncoding = defaultEncoding;
}
/**
* Return the default encoding for {@link MimeMessage MimeMessages},
* or {@code null} if none.
*/
@Nullable
public String getDefaultEncoding() {
return this.defaultEncoding;
}
/**
* Set the default Java Activation {@link FileTypeMap} to use for
* {@link MimeMessage MimeMessages} created by this instance.
* <p>A {@code FileTypeMap} specified here will be autodetected by
* {@link MimeMessageHelper}, avoiding the need to specify the
* {@code FileTypeMap} for each {@code MimeMessageHelper} instance.
* <p>For example, you can specify a custom instance of Spring's
* {@link ConfigurableMimeFileTypeMap} here. If not explicitly specified,
* a default {@code ConfigurableMimeFileTypeMap} will be used, containing
* an extended set of MIME type mappings (as defined by the
* {@code mime.types} file contained in the Spring jar).
*
* @see MimeMessageHelper#setFileTypeMap
*/
public void setDefaultFileTypeMap(@Nullable FileTypeMap defaultFileTypeMap) {
this.defaultFileTypeMap = defaultFileTypeMap;
}
/**
* Return the default Java Activation {@link FileTypeMap} for
* {@link MimeMessage MimeMessages}, or {@code null} if none.
*/
@Nullable
public FileTypeMap getDefaultFileTypeMap() {
return this.defaultFileTypeMap;
}
//---------------------------------------------------------------------
// Implementation of MailSender
//---------------------------------------------------------------------
@Override
public void send(SimpleMailMessage simpleMessage) throws MailException {
send(new SimpleMailMessage[]{simpleMessage});
}
@Override
public void send(SimpleMailMessage... simpleMessages) throws MailException {
List<MimeMessage> mimeMessages = new ArrayList<>(simpleMessages.length);
for (SimpleMailMessage simpleMessage : simpleMessages) {
MimeMailMessage message = new MimeMailMessage(createMimeMessage());
simpleMessage.copyTo(message);
mimeMessages.add(message.getMimeMessage());
}
doSend(mimeMessages.toArray(new MimeMessage[0]), simpleMessages);
}
//---------------------------------------------------------------------
// Implementation of JavaMailSender
//---------------------------------------------------------------------
/**
* This implementation creates a SmartMimeMessage, holding the specified
* default encoding and default FileTypeMap. This special defaults-carrying
* message will be autodetected by {@link MimeMessageHelper}, which will use
* the carried encoding and FileTypeMap unless explicitly overridden.
*
* @see #setDefaultEncoding
* @see #setDefaultFileTypeMap
*/
@Override
public MimeMessage createMimeMessage() {
return new SmartMimeMessage(getSession(), getDefaultEncoding(), getDefaultFileTypeMap());
}
@Override
public MimeMessage createMimeMessage(InputStream contentStream) throws MailException {
try {
return new MimeMessage(getSession(), contentStream);
} catch (Exception ex) {
throw new MailParseException("Could not parse raw MIME content", ex);
}
}
@Override
public void send(MimeMessage mimeMessage) throws MailException {
send(new MimeMessage[]{mimeMessage});
}
@Override
public void send(MimeMessage... mimeMessages) throws MailException {
doSend(mimeMessages, null);
}
@Override
public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
send(new MimeMessagePreparator[]{mimeMessagePreparator});
}
@Override
public void send(MimeMessagePreparator... mimeMessagePreparators) throws MailException {
try {
List<MimeMessage> mimeMessages = new ArrayList<>(mimeMessagePreparators.length);
for (MimeMessagePreparator preparator : mimeMessagePreparators) {
MimeMessage mimeMessage = createMimeMessage();
preparator.prepare(mimeMessage);
mimeMessages.add(mimeMessage);
}
send(mimeMessages.toArray(new MimeMessage[0]));
} catch (MailException ex) {
throw ex;
} catch (MessagingException ex) {
throw new MailParseException(ex);
} catch (Exception ex) {
throw new MailPreparationException(ex);
}
}
/**
* Validate that this instance can connect to the server that it is configured
* for. Throws a {@link MessagingException} if the connection attempt failed.
*/
public void testConnection() throws MessagingException {
Transport transport = null;
try {
transport = connectTransport();
} finally {
if (transport != null) {
transport.close();
}
}
}
/**
* Actually send the given array of MimeMessages via JavaMail.
*
* @param mimeMessages the MimeMessage objects to send
* @param originalMessages corresponding original message objects
* that the MimeMessages have been created from (with same array
* length and indices as the "mimeMessages" array), if any
* @throws MailAuthenticationException in case of authentication failure
* @throws MailSendException in case of failure when sending a message
*/
protected void doSend(MimeMessage[] mimeMessages, @Nullable Object[] originalMessages) throws MailException {
Map<Object, Exception> failedMessages = new LinkedHashMap<>();
Transport transport = null;
try {
for (int i = 0; i < mimeMessages.length; i++) {
// Check transport connection first...
if (transport == null || !transport.isConnected()) {
if (transport != null) {
try {
transport.close();
} catch (Exception ex) {
// Ignore - we're reconnecting anyway
}
transport = null;
}
try {
transport = connectTransport();
} catch (AuthenticationFailedException ex) {
throw new MailAuthenticationException(ex);
} catch (Exception ex) {
// Effectively, all remaining messages failed...
for (int j = i; j < mimeMessages.length; j++) {
Object original = (originalMessages != null ? originalMessages[j] : mimeMessages[j]);
failedMessages.put(original, ex);
}
throw new MailSendException("Mail server connection failed", ex, failedMessages);
}
}
// Send message via current transport...
MimeMessage mimeMessage = mimeMessages[i];
try {
if (mimeMessage.getSentDate() == null) {
mimeMessage.setSentDate(new Date());
}
String messageId = mimeMessage.getMessageID();
mimeMessage.saveChanges();
if (messageId != null) {
// Preserve explicitly specified message id...
mimeMessage.setHeader(HEADER_MESSAGE_ID, messageId);
}
Address[] addresses = mimeMessage.getAllRecipients();
transport.sendMessage(mimeMessage, (addresses != null ? addresses : new Address[0]));
} catch (Exception ex) {
Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
failedMessages.put(original, ex);
}
}
} finally {
try {
if (transport != null) {
transport.close();
}
} catch (Exception ex) {
if (!failedMessages.isEmpty()) {
throw new MailSendException("Failed to close server connection after message failures", ex,
failedMessages);
} else {
throw new MailSendException("Failed to close server connection after message sending", ex);
}
}
}
if (!failedMessages.isEmpty()) {
throw new MailSendException(failedMessages);
}
}
/**
* Obtain and connect a Transport from the underlying JavaMail Session,
* passing in the specified host, port, username, and password.
*
* @return the connected Transport object
* @throws MessagingException if the connect attempt failed
* @see #getTransport
* @see #getHost()
* @see #getPort()
* @see #getUsername()
* @see #getPassword()
* @since 4.1.2
*/
protected Transport connectTransport() throws MessagingException {
String username = getUsername();
String password = getPassword();
if ("".equals(username)) { // probably from a placeholder
username = null;
if ("".equals(password)) { // in conjunction with "" username, this means no password to use
password = null;
}
}
Transport transport = getTransport(getSession());
transport.connect(getHost(), getPort(), username, password);
return transport;
}
/**
* Obtain a Transport object from the given JavaMail Session,
* using the configured protocol.
* <p>Can be overridden in subclasses, e.g. to return a mock Transport object.
*
* @see Session#getTransport(String)
* @see #getSession()
* @see #getProtocol()
*/
protected Transport getTransport(Session session) throws NoSuchProviderException {
String protocol = getProtocol();
if (protocol == null) {
protocol = session.getProperty("mail.transport.protocol");
if (protocol == null) {
protocol = DEFAULT_PROTOCOL;
}
}
return session.getTransport(protocol);
}
}

View File

@ -1,160 +0,0 @@
package com.simaek.notify.email.embedded.mail.javamail;
import com.simaek.notify.email.embedded.mail.MailMessage;
import com.simaek.notify.email.embedded.mail.MailParseException;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
/**
* Implementation of the MailMessage interface for a JavaMail MIME message,
* to let message population code interact with a simple message or a MIME
* message through a common interface.
*
* <p>Uses a MimeMessageHelper underneath. Can either be created with a
* MimeMessageHelper instance or with a JavaMail MimeMessage instance.
*
* @author Juergen Hoeller
* @see MimeMessageHelper
* @see MimeMessage
* @since 1.1.5
*/
public class MimeMailMessage implements MailMessage {
private final MimeMessageHelper helper;
/**
* Create a new MimeMailMessage based on the given MimeMessageHelper.
*
* @param mimeMessageHelper the MimeMessageHelper
*/
public MimeMailMessage(MimeMessageHelper mimeMessageHelper) {
this.helper = mimeMessageHelper;
}
/**
* Create a new MimeMailMessage based on the given JavaMail MimeMessage.
*
* @param mimeMessage the JavaMail MimeMessage
*/
public MimeMailMessage(MimeMessage mimeMessage) {
this.helper = new MimeMessageHelper(mimeMessage);
}
/**
* Return the MimeMessageHelper that this MimeMailMessage is based on.
*/
public final MimeMessageHelper getMimeMessageHelper() {
return this.helper;
}
/**
* Return the JavaMail MimeMessage that this MimeMailMessage is based on.
*/
public final MimeMessage getMimeMessage() {
return this.helper.getMimeMessage();
}
@Override
public void setFrom(String from) throws MailParseException {
try {
this.helper.setFrom(from);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setReplyTo(String replyTo) throws MailParseException {
try {
this.helper.setReplyTo(replyTo);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setTo(String to) throws MailParseException {
try {
this.helper.setTo(to);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setTo(String... to) throws MailParseException {
try {
this.helper.setTo(to);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setCc(String cc) throws MailParseException {
try {
this.helper.setCc(cc);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setCc(String... cc) throws MailParseException {
try {
this.helper.setCc(cc);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setBcc(String bcc) throws MailParseException {
try {
this.helper.setBcc(bcc);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setBcc(String... bcc) throws MailParseException {
try {
this.helper.setBcc(bcc);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setSentDate(Date sentDate) throws MailParseException {
try {
this.helper.setSentDate(sentDate);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setSubject(String subject) throws MailParseException {
try {
this.helper.setSubject(subject);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
@Override
public void setText(String text) throws MailParseException {
try {
this.helper.setText(text);
} catch (MessagingException ex) {
throw new MailParseException(ex);
}
}
}

View File

@ -1,39 +0,0 @@
package com.simaek.notify.email.embedded.mail.javamail;
import javax.mail.internet.MimeMessage;
/**
* Callback interface for the preparation of JavaMail MIME messages.
*
* <p>The corresponding {@code send} methods of {@link JavaMailSender}
* will take care of the actual creation of a {@link MimeMessage} instance,
* and of proper exception conversion.
*
* <p>It is often convenient to use a {@link MimeMessageHelper} for populating
* the passed-in MimeMessage, in particular when working with attachments or
* special character encodings.
* See {@link MimeMessageHelper MimeMessageHelper's javadoc} for an example.
*
* @author Juergen Hoeller
* @see JavaMailSender#send(MimeMessagePreparator)
* @see JavaMailSender#send(MimeMessagePreparator[])
* @see MimeMessageHelper
* @since 07.10.2003
*/
@FunctionalInterface
public interface MimeMessagePreparator {
/**
* Prepare the given new MimeMessage instance.
*
* @param mimeMessage the message to prepare
* @throws javax.mail.MessagingException passing any exceptions thrown by MimeMessage
* methods through for automatic conversion to the MailException hierarchy
* @throws java.io.IOException passing any exceptions thrown by MimeMessage methods
* through for automatic conversion to the MailException hierarchy
* @throws Exception if mail preparation failed, for example when a
* FreeMarker template cannot be rendered for the mail text
*/
void prepare(MimeMessage mimeMessage) throws Exception;
}

View File

@ -1,65 +0,0 @@
package com.simaek.notify.email.embedded.mail.javamail;
import org.springframework.lang.Nullable;
import javax.activation.FileTypeMap;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
/**
* Special subclass of the standard JavaMail {@link MimeMessage}, carrying a
* default encoding to be used when populating the message and a default Java
* Activation {@link FileTypeMap} to be used for resolving attachment types.
*
* <p>Created by {@link JavaMailSenderImpl} in case of a specified default encoding
* and/or default FileTypeMap. Autodetected by {@link MimeMessageHelper}, which
* will use the carried encoding and FileTypeMap unless explicitly overridden.
*
* @author Juergen Hoeller
* @see JavaMailSenderImpl#createMimeMessage()
* @see MimeMessageHelper#getDefaultEncoding(MimeMessage)
* @see MimeMessageHelper#getDefaultFileTypeMap(MimeMessage)
* @since 1.2
*/
class SmartMimeMessage extends MimeMessage {
@Nullable
private final String defaultEncoding;
@Nullable
private final FileTypeMap defaultFileTypeMap;
/**
* Create a new SmartMimeMessage.
*
* @param session the JavaMail Session to create the message for
* @param defaultEncoding the default encoding, or {@code null} if none
* @param defaultFileTypeMap the default FileTypeMap, or {@code null} if none
*/
public SmartMimeMessage(
Session session, @Nullable String defaultEncoding, @Nullable FileTypeMap defaultFileTypeMap) {
super(session);
this.defaultEncoding = defaultEncoding;
this.defaultFileTypeMap = defaultFileTypeMap;
}
/**
* Return the default encoding of this message, or {@code null} if none.
*/
@Nullable
public final String getDefaultEncoding() {
return this.defaultEncoding;
}
/**
* Return the default FileTypeMap of this message, or {@code null} if none.
*/
@Nullable
public final FileTypeMap getDefaultFileTypeMap() {
return this.defaultFileTypeMap;
}
}

View File

@ -1,326 +0,0 @@
################################################################################
# Copyright 2002-2019 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################################################################################
################################################################################
#
# Defaults for the Java Activation Framework (revised).
#
# Modified extensions registered in this file:
# text/plain java c c++ cpp pl cc h
# image/png png
# image/svg+xml svg
#
################################################################################
text/html html htm HTML HTM
text/plain txt text TXT TEXT java c c++ cpp pl cc h
image/gif gif GIF
image/ief ief
image/jpeg jpeg jpg jpe JPG
image/tiff tiff tif
image/x-xwindowdump xwd
application/postscript ai eps ps
application/rtf rtf
application/x-tex tex
application/x-texinfo texinfo texi
application/x-troff t tr roff
audio/basic au
audio/midi midi mid
audio/x-aifc aifc
audio/x-aiff aif aiff
audio/x-mpeg mpeg mpg
audio/x-wav wav
video/mpeg mpeg mpg mpe
video/quicktime qt mov
video/x-msvideo avi
################################################################################
#
# Additional file types adapted from
# http://sites.utoronto.ca/webdocs/HTMLdocs/Book/Book-3ed/appb/mimetype.html
# kindly re-licensed to Apache Software License 2.0 by Ian Graham.
#
################################################################################
# TEXT TYPES
text/x-speech talk
text/css css
text/csv csv
# IMAGE TYPES
# X-Windows bitmap (b/w)
image/x-xbitmap xbm
# X-Windows pixelmap (8-bit color)
image/x-xpixmap xpm
# Portable Network Graphics
image/png png
# Scalable Vector Graphics
image/svg+xml svg
# Image Exchange Format (RFC 1314)
image/ief ief
# RGB
image/rgb rgb
# Group III Fax (RFC 1494)
image/g3fax g3f
# X Windowdump format
image/x-xwindowdump xwd
# Macintosh PICT format
image/x-pict pict
# PPM (UNIX PPM package)
image/x-portable-pixmap ppm
# PGM (UNIX PPM package)
image/x-portable-graymap pgm
# PBM (UNIX PPM package)
image/x-portable-bitmap pbm
# PNM (UNIX PPM package)
image/x-portable-anymap pnm
# Microsoft Windows bitmap
image/x-ms-bmp bmp
# CMU raster
image/x-cmu-raster ras
# Kodak Photo-CD
image/x-photo-cd pcd
# Computer Graphics Metafile
image/cgm cgm
# CALS Type 1 or 2
image/x-cals mil cal
# Fractal Image Format (Iterated Systems)
image/fif fif
# QuickSilver active image (Micrografx)
image/x-mgx-dsf dsf
# CMX vector image (Corel)
image/x-cmx cmx
# Wavelet-compressed (Summus)
image/wavelet wi
# AutoCad Drawing (SoftSource)
image/vnd.dwg dwg
# AutoCad DXF file (SoftSource)
image/vnd.dxf dxf
# Simple Vector Format (SoftSource)
image/vnd.svf svf
# AUDIO/VOICE/MUSIC RELATED TYPES
# """basic""audio - 8-bit u-law PCM"
audio/basic au snd
# Macintosh audio format (AIpple)
audio/x-aiff aif aiff aifc
# Microsoft audio
audio/x-wav wav
# MPEG audio
audio/x-mpeg mpa abs mpega
# MPEG-2 audio
audio/x-mpeg-2 mp2a mpa2
# compressed speech (Echo Speech Corp.)
audio/echospeech es
# Toolvox speech audio (Voxware)
audio/voxware vox
# RapidTransit compressed audio (Fast Man)
application/fastman lcc
# Realaudio (Progressive Networks)
application/x-pn-realaudio ra ram
# MIDI music data
x-music/x-midi mmid
# Koan music data (SSeyo)
application/vnd.koan skp
# Speech synthesis data (MVP Solutions)
text/x-speech talk
# VIDEO TYPES
# MPEG video
video/mpeg mpeg mpg mpe
# MPEG-2 video
video/mpeg-2 mpv2 mp2v
# Macintosh Quicktime
video/quicktime qt mov
# Microsoft video
video/x-msvideo avi
# SGI Movie format
video/x-sgi-movie movie
# VDOlive streaming video (VDOnet)
video/vdo vdo
# Vivo streaming video (Vivo software)
video/vnd.vivo viv
# SPECIAL HTTP/WEB APPLICATION TYPES
# Proxy autoconfiguration (Netscape browsers)
application/x-ns-proxy-autoconfig pac
# Netscape Cooltalk chat data (Netscape)
x-conference/x-cooltalk ice
# TEXT-RELATED
# PostScript
application/postscript ai eps ps
# Microsoft Rich Text Format
application/rtf rtf
# Adobe Acrobat PDF
application/pdf pdf
# Maker Interchange Format (FrameMaker)
application/vnd.mif mif
# Troff document
application/x-troff t tr roff
# Troff document with MAN macros
application/x-troff-man man
# Troff document with ME macros
application/x-troff-me me
# Troff document with MS macros
application/x-troff-ms ms
# LaTeX document
application/x-latex latex
# Tex/LateX document
application/x-tex tex
# GNU TexInfo document
application/x-texinfo texinfo texi
# TeX dvi format
application/x-dvi dvi
# MS word document
application/msword doc DOC
# Office Document Architecture
application/oda oda
# Envoy Document
application/envoy evy
# ARCHIVE/COMPRESSED ARCHIVES
# Gnu tar format
application/x-gtar gtar
# 4.3BSD tar format
application/x-tar tar
# POSIX tar format
application/x-ustar ustar
# Old CPIO format
application/x-bcpio bcpio
# POSIX CPIO format
application/x-cpio cpio
# UNIX sh shell archive
application/x-shar shar
# DOS/PC - Pkzipped archive
application/zip zip
# Macintosh Binhexed archive
application/mac-binhex40 hqx
# Macintosh Stuffit Archive
application/x-stuffit sit sea
# Fractal Image Format
application/fractals fif
# "Binary UUencoded"
application/octet-stream bin uu
# PC executable
application/octet-stream exe
# "WAIS ""sources"""
application/x-wais-source src wsrc
# NCSA HDF data format
application/hdf hdf
# DOWNLOADABLE PROGRAM/SCRIPTS
# Javascript program
text/javascript js ls mocha
# UNIX bourne shell program
application/x-sh sh
# UNIX c-shell program
application/x-csh csh
# Perl program
application/x-perl pl
# Tcl (Tool Control Language) program
application/x-tcl tcl
# ANIMATION/MULTIMEDIA
# FutureSplash vector animation (FutureWave)
application/futuresplash spl
# mBED multimedia data (mBED)
application/mbedlet mbd
# PowerMedia multimedia (RadMedia)
application/x-rad-powermedia rad
# PRESENTATION
# PowerPoint presentation (Microsoft)
application/mspowerpoint ppz
# ASAP WordPower (Software Publishing Corp.)
application/x-asap asp
# Astound Web Player multimedia data (GoldDisk)
application/astound asn
# SPECIAL EMBEDDED OBJECT
# OLE script e.g. Visual Basic (Ncompass)
application/x-olescript axs
# OLE Object (Microsoft/NCompass)
application/x-oleobject ods
# OpenScape OLE/OCX objects (Business@Web)
x-form/x-openscape opp
# Visual Basic objects (Amara)
application/x-webbasic wba
# Specialized data entry forms (Alpha Software)
application/x-alpha-form frm
# client-server objects (Wayfarer Communications)
x-script/x-wfxclient wfx
# GENERAL APPLICATIONS
# Undefined binary data (often executable progs)
application/octet-stream exe com
# Pointcast news data (Pointcast)
application/x-pcn pcn
# Excel spreadsheet (Microsoft)
application/vnd.ms-excel xls
# PowerPoint (Microsoft)
application/vnd.ms-powerpoint ppt
# Microsoft Project (Microsoft)
application/vnd.ms-project mpp
# SourceView document (Dataware Electronics)
application/vnd.svd svd
# Net Install - software install (20/20 Software)
application/x-net-install ins
# Carbon Copy - remote control/access (Microcom)
application/ccv ccv
# Spreadsheets (Visual Components)
workbook/formulaone vts
# 2D/3D DATA/VIRTUAL REALITY TYPES
# VRML data file
x-world/x-vrml wrl vrml
# WIRL - VRML data (VREAM)
x-world/x-vream vrw
# Play3D 3d scene data (Play3D)
application/x-p3d p3d
# Viscape Interactive 3d world data (Superscape)
x-world/x-svr svr
# WebActive 3d data (Plastic Thought)
x-world/x-wvr wvr
# QuickDraw3D scene data (Apple)
x-world/x-3dmf 3dmf
# SCIENTIFIC/MATH/CAD TYPES
# Mathematica notebook
application/mathematica ma
# Computational meshes for numerical simulations
x-model/x-mesh msh
# Vis5D 5-dimensional data
application/vis5d v5d
# IGES models -- CAD/CAM (CGM) data
application/iges igs
# Autocad WHIP vector drawings
drawing/x-dwf dwf

View File

@ -1,11 +0,0 @@
/**
* JavaMail support for Spring's mail infrastructure.
* Provides an extended JavaMailSender interface and a MimeMessageHelper
* class for convenient population of a JavaMail MimeMessage.
*/
@NonNullApi
@NonNullFields
package com.simaek.notify.email.embedded.mail.javamail;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

View File

@ -1,10 +0,0 @@
/**
* Spring's generic mail infrastructure.
* Concrete implementations are provided in the subpackages.
*/
@NonNullApi
@NonNullFields
package com.simaek.notify.email.embedded.mail;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

View File

@ -1,12 +1,12 @@
package com.simaek.notify.email; package com.cicdi.notify.email;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.template.AbstractTemplateManager; import com.cicdi.notify.template.AbstractTemplateManager;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateManager; import com.cicdi.notify.template.TemplateManager;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.email.embedded.DefaultEmailNotifierProvider; import com.cicdi.notify.email.embedded.DefaultEmailNotifierProvider;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
@ -23,28 +23,31 @@ public class DefaultEmailTest {
@Test @Test
public void testSend() { public void testSend() {
// 通知器配置管理器 // 通知器配置管理器
NotifyConfigManager notifyConfigManager = (notifyType, configId) -> { NotifyConfigManager notifyConfigManager = new NotifyConfigManager() {
NotifierProperties notifierProperties = new NotifierProperties(); @Override
notifierProperties.setType(DefaultNotifyType.email.getId()); public NotifierProperties getNotifyConfig(NotifyType notifyType, String configId) {
notifierProperties.setProvider(EmailProvider.embedded.getId()); NotifierProperties notifierProperties = new NotifierProperties();
notifierProperties.setId("12"); notifierProperties.setType(DefaultNotifyType.email.getId());
notifierProperties.setProvider(EmailProvider.embedded.getId());
notifierProperties.setId("12");
Map<String, Object> config = new HashMap<>(); Map<String, Object> config = new HashMap<>();
config.put("host", "nas.xueye.io"); config.put("host", "nas.xueye.io");
config.put("port", 587); config.put("port", 587);
config.put("username", "xueye"); config.put("username", "xueye");
config.put("password", "snow@PX1314"); config.put("password", "snow@PX1314");
config.put("sender", "master@simaek.com"); config.put("sender", "master@simaek.com");
Map<String, Object> p1 = new HashMap<>(); Map<String, Object> p1 = new HashMap<>();
p1.put("name", "mail.smtp.starttls.enable"); p1.put("name", "mail.smtp.starttls.enable");
p1.put("value", "true"); p1.put("value", "true");
Map<String, Object> p2 = new HashMap<>(); Map<String, Object> p2 = new HashMap<>();
p2.put("name", "mail.smtp.auth"); p2.put("name", "mail.smtp.auth");
p2.put("value", "true"); p2.put("value", "true");
config.put("properties", Arrays.asList(p1, p2)); config.put("properties", Arrays.asList(p1, p2));
notifierProperties.setConfiguration(config); notifierProperties.setConfiguration(config);
return notifierProperties; return notifierProperties;
}
}; };
// 模板管理器 // 模板管理器

View File

@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>notify-parent</artifactId> <artifactId>notify</artifactId>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<version>0.1.1</version> <version>0.1.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -19,8 +19,9 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<artifactId>notify-core</artifactId> <artifactId>notify-core</artifactId>
<version>0.1.0</version>
</dependency> </dependency>
<dependency> <dependency>
@ -31,11 +32,12 @@
<dependency> <dependency>
<groupId>com.aliyun</groupId> <groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId> <artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>okhttp</artifactId> <artifactId>httpclient</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,6 +1,6 @@
package com.simaek.notify.sms; package com.cicdi.notify.sms;
import com.simaek.notify.Provider; import com.cicdi.notify.Provider;
/** /**
* @author xueye * @author xueye

View File

@ -1,6 +1,6 @@
package com.simaek.notify.sms; package com.cicdi.notify.sms;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.sms.aliyun; package com.cicdi.notify.sms.aliyun;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
@ -9,8 +9,8 @@ import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType; import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile; import com.aliyuncs.profile.IClientProfile;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.sms.SmsProvider; import com.cicdi.notify.sms.SmsProvider;
import java.util.Map; import java.util.Map;

View File

@ -1,11 +1,12 @@
package com.simaek.notify.sms.aliyun; package com.cicdi.notify.sms.aliyun;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.sms.SmsProvider; import com.cicdi.notify.sms.SmsProvider;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateManager;
import com.simaek.notify.template.TemplateProvider; import com.cicdi.notify.template.TemplateProperties;
import com.cicdi.notify.template.TemplateProvider;
/** /**
* 阿里云短信通知服务 * 阿里云短信通知服务

View File

@ -1,7 +1,7 @@
package com.simaek.notify.sms.aliyun; package com.cicdi.notify.sms.aliyun;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import java.util.Map; import java.util.Map;

View File

@ -1,14 +1,21 @@
package com.simaek.notify.sms.telecom; package com.cicdi.notify.sms.telecom;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.sms.SmsProvider; import com.cicdi.notify.sms.SmsProvider;
import com.simaek.notify.util.ExpressionUtils; import com.cicdi.notify.template.TemplateManager;
import okhttp3.*; import com.cicdi.notify.util.ExpressionUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* 云信通短信通知平台通知器 * 云信通短信通知平台通知器
@ -23,12 +30,12 @@ public class TelecomSmsNotifier implements Notifier<TelecomSmsTemplate> {
private final String notifierId; private final String notifierId;
private final OkHttpClient httpClient; private final CloseableHttpClient httpClient;
public TelecomSmsNotifier(NotifierProperties properties) { public TelecomSmsNotifier(NotifierProperties properties) {
this.httpClient = HttpClientBuilder.create().build();
this.notifierId = properties.getId(); this.notifierId = properties.getId();
this.configuration = new JSONObject(properties.getConfiguration()).toJavaObject(TelecomSmsNotifierConfiguration.class); this.configuration = new JSONObject(properties.getConfiguration()).toJavaObject(TelecomSmsNotifierConfiguration.class);
this.httpClient = new OkHttpClient.Builder().build();
} }
@Override @Override
@ -49,22 +56,20 @@ public class TelecomSmsNotifier implements Notifier<TelecomSmsTemplate> {
@Override @Override
public void send(TelecomSmsTemplate template, Map<String, Object> context) { public void send(TelecomSmsTemplate template, Map<String, Object> context) {
try { try {
HttpUrl url = Objects.requireNonNull(HttpUrl.parse(notifyApi)).newBuilder() URI sendMsgURI = new URIBuilder(notifyApi).addParameter("userId", configuration.getUserId())
.addQueryParameter("userId", configuration.getUserId()) .addParameter("password", configuration.getPassword())
.addQueryParameter("password", configuration.getPassword()) .addParameter("content", render(template.getContent(), context))
.addQueryParameter("content", render(template.getContent(), context)) .addParameter("mobile", template.getMobile())
.addQueryParameter("mobile", template.getMobile())
.build(); .build();
Request request = new Request.Builder() HttpPost httpPost = new HttpPost(sendMsgURI);
.url(url) CloseableHttpResponse response = httpClient.execute(httpPost);
.post(RequestBody.create(new byte[0])) String responseString = EntityUtils.toString(response.getEntity());
.build(); Map<String, String> resultMap = handleResponse(responseString);
Call call = httpClient.newCall(request);
Response response = call.execute();
Map<String, String> resultMap = handleResponse(Objects.requireNonNull(response.body()).string());
String resultCodeKey = "rspCode"; String resultCodeKey = "rspCode";
if (!resultMap.containsKey(resultCodeKey) || (!"0".equals(resultMap.get(resultCodeKey)) && !"DELIVRD".equalsIgnoreCase(resultMap.get(resultCodeKey)))) { if (resultMap.containsKey(resultCodeKey)) {
throw new RuntimeException("短信发送失败:" + resultMap.get("rspDesc")); if (!"0".equals(resultMap.get(resultCodeKey)) && !"DELIVRD".equalsIgnoreCase(resultMap.get(resultCodeKey))) {
throw new RuntimeException("短信发送失败:" + resultMap.get("rspDesc"));
}
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -73,6 +78,11 @@ public class TelecomSmsNotifier implements Notifier<TelecomSmsTemplate> {
@Override @Override
public void close() { public void close() {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
/** /**

View File

@ -1,4 +1,4 @@
package com.simaek.notify.sms.telecom; package com.cicdi.notify.sms.telecom;
/** /**
* 云信通短信通知平台配置信息 * 云信通短信通知平台配置信息

View File

@ -1,11 +1,11 @@
package com.simaek.notify.sms.telecom; package com.cicdi.notify.sms.telecom;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.sms.SmsProvider; import com.cicdi.notify.sms.SmsProvider;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.template.TemplateProvider; import com.cicdi.notify.template.TemplateProvider;
/** /**
* @author xueye * @author xueye

View File

@ -1,6 +1,6 @@
package com.simaek.notify.sms.telecom; package com.cicdi.notify.sms.telecom;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
/** /**
* @author xueye * @author xueye

View File

@ -1,11 +1,11 @@
package com.simaek.notify.sms; package com.cicdi.notify.sms;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.sms.aliyun.AliyunSmsNotifierProvider; import com.cicdi.notify.sms.aliyun.AliyunSmsNotifierProvider;
import com.simaek.notify.template.AbstractTemplateManager; import com.cicdi.notify.template.AbstractTemplateManager;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateManager; import com.cicdi.notify.template.TemplateManager;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import org.junit.Test; import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;

View File

@ -1,13 +1,13 @@
package com.simaek.notify.sms; package com.cicdi.notify.sms;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.sms.telecom.TelecomSmsNotifierProvider; import com.cicdi.notify.sms.telecom.TelecomSmsNotifierProvider;
import com.simaek.notify.sms.telecom.TelecomSmsTemplate; import com.cicdi.notify.sms.telecom.TelecomSmsTemplate;
import com.simaek.notify.template.AbstractTemplateManager; import com.cicdi.notify.template.AbstractTemplateManager;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateManager; import com.cicdi.notify.template.TemplateManager;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import org.junit.Test; import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;
@ -45,7 +45,7 @@ public class TelecomSmsTest {
TelecomSmsTemplate template = new TelecomSmsTemplate(); TelecomSmsTemplate template = new TelecomSmsTemplate();
template.setContent("${code}有效期为5分钟。"); template.setContent("${code}有效期为5分钟。");
template.setMobile("18605120786"); template.setMobile("13047689449,18605120786");
templateProperties.setTemplate(JSON.toJSONString(template)); templateProperties.setTemplate(JSON.toJSONString(template));

View File

@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>notify-parent</artifactId> <artifactId>notify</artifactId>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<version>0.1.1</version> <version>0.1.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -19,20 +19,26 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<artifactId>notify-core</artifactId> <artifactId>notify-core</artifactId>
<version>0.1.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>okhttp</artifactId> <artifactId>httpclient</artifactId>
</dependency> </dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,6 +1,6 @@
package com.simaek.notify.wechat; package com.cicdi.notify.wechat;
import com.simaek.notify.Provider; import com.cicdi.notify.Provider;
public enum WechatProvider implements Provider { public enum WechatProvider implements Provider {
corpMessage("微信企业消息通知"), corpMessage("微信企业消息通知"),

View File

@ -1,18 +1,28 @@
package com.simaek.notify.wechat.corp; package com.cicdi.notify.wechat.corp;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.DefaultNotifyType; import com.cicdi.notify.DefaultNotifyType;
import com.simaek.notify.Notifier; import com.cicdi.notify.Notifier;
import com.simaek.notify.NotifyType; import com.cicdi.notify.NotifyType;
import com.simaek.notify.Provider; import com.cicdi.notify.Provider;
import com.simaek.notify.wechat.WechatProvider; import com.cicdi.notify.wechat.WechatProvider;
import okhttp3.*; import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException; import java.io.IOException;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
public class WechatCorpNotifier implements Notifier<WechatCorpTemplate> { public class WechatCorpNotifier implements Notifier<WechatCorpTemplate> {
@ -30,12 +40,9 @@ public class WechatCorpNotifier implements Notifier<WechatCorpTemplate> {
private final String notifierId; private final String notifierId;
private final OkHttpClient httpClient;
public WechatCorpNotifier(String id, WechatCorpProperties properties) { public WechatCorpNotifier(String id, WechatCorpProperties properties) {
this.properties = properties; this.properties = properties;
this.notifierId = id; this.notifierId = id;
this.httpClient = new OkHttpClient.Builder().build();
} }
@Override @Override
@ -55,18 +62,17 @@ public class WechatCorpNotifier implements Notifier<WechatCorpTemplate> {
@Override @Override
public void send(WechatCorpTemplate template, Map<String, Object> context) { public void send(WechatCorpTemplate template, Map<String, Object> context) {
HttpUrl url = Objects.requireNonNull(HttpUrl.parse(notifyApi)).newBuilder() CloseableHttpClient httpClient = HttpClientBuilder.create().build();
.addQueryParameter("access_token", getToken()) HttpPost httpPost = new HttpPost(notifyApi + "?access_token=" + getToken());
.build(); httpPost.setHeader("Content-Type", "application/json;charset=utf8");
Request request = new Request.Builder()
.url(url) StringEntity stringEntity = new StringEntity(template.createJsonRequest(context), "UTF-8");
.post(RequestBody.create(template.createJsonRequest(context), MediaType.get("application/json"))) httpPost.setEntity(stringEntity);
.header("Content-Type", "application/json;charset=utf8")
.build();
try { try {
Call call = httpClient.newCall(request); CloseableHttpResponse response = httpClient.execute(httpPost);
Response response = call.execute(); String result = EntityUtils.toString(response.getEntity());
String result = Objects.requireNonNull(response.body()).string(); System.out.println(result);
JSONObject jsonObject = JSON.parseObject(result); JSONObject jsonObject = JSON.parseObject(result);
if (!"0".equals(jsonObject.get("errcode").toString())) { if (!"0".equals(jsonObject.get("errcode").toString())) {
throw new RuntimeException("发送微信企业通知失败:" + jsonObject.get("errmsg")); throw new RuntimeException("发送微信企业通知失败:" + jsonObject.get("errmsg"));
@ -84,18 +90,15 @@ public class WechatCorpNotifier implements Notifier<WechatCorpTemplate> {
} }
private String requestToken() { private String requestToken() {
HttpUrl url = Objects.requireNonNull(HttpUrl.parse(tokenApi)).newBuilder() List<NameValuePair> params = new ArrayList<>();
.addQueryParameter("corpId", properties.getCorpId()) params.add(new BasicNameValuePair("corpId", properties.getCorpId()));
.addQueryParameter("corpSecret", properties.getCorpSecret()) params.add(new BasicNameValuePair("corpSecret", properties.getCorpSecret()));
.build();
Request request = new Request.Builder() CloseableHttpClient httpClient = HttpClientBuilder.create().build();
.url(url)
.get()
.build();
try { try {
Call call = httpClient.newCall(request); HttpGet httpGet = new HttpGet(new URIBuilder(tokenApi).setParameters(params).build());
Response response = call.execute(); CloseableHttpResponse response = httpClient.execute(httpGet);
JSONObject responseJson = JSON.parseObject(Objects.requireNonNull(response.body()).string()); JSONObject responseJson = JSON.parseObject(EntityUtils.toString(response.getEntity()));
if (responseJson.containsKey("access_token")) { if (responseJson.containsKey("access_token")) {
String access_token = responseJson.get("access_token").toString(); String access_token = responseJson.get("access_token").toString();
accessToken = access_token; accessToken = access_token;

View File

@ -1,11 +1,11 @@
package com.simaek.notify.wechat.corp; package com.cicdi.notify.wechat.corp;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.template.TemplateProvider; import com.cicdi.notify.template.TemplateProvider;
import com.simaek.notify.wechat.WechatProvider; import com.cicdi.notify.wechat.WechatProvider;
import java.util.Map; import java.util.Map;

View File

@ -1,4 +1,4 @@
package com.simaek.notify.wechat.corp; package com.cicdi.notify.wechat.corp;
public class WechatCorpProperties { public class WechatCorpProperties {

View File

@ -1,8 +1,8 @@
package com.simaek.notify.wechat.corp; package com.cicdi.notify.wechat.corp;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.util.StringUtils; import org.apache.commons.lang.StringUtils;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -68,10 +68,10 @@ public class WechatCorpTemplate implements Template {
json.put("msgtype", "text"); json.put("msgtype", "text");
json.put("text", Collections.singletonMap("content", message)); json.put("text", Collections.singletonMap("content", message));
if (!StringUtils.isBlank(toUser)) { if (StringUtils.isNotBlank(toUser)) {
json.put("touser", this.createUserIdList(context)); json.put("touser", this.createUserIdList(context));
} }
if (!StringUtils.isBlank(toParty)) { if (StringUtils.isNotBlank(toParty)) {
json.put("toparty", this.createDepartmentIdList(context)); json.put("toparty", this.createDepartmentIdList(context));
} }

View File

@ -1,15 +1,30 @@
package com.simaek.notify.wechat.subscription; package com.cicdi.notify.wechat.subscription;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.wechat.WechatProvider; import com.cicdi.notify.wechat.WechatProvider;
import okhttp3.*; import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Duration; import java.time.Duration;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
/** /**
@ -50,11 +65,11 @@ public class WechatSubscriptionNotifier implements Notifier<WechatSubscriptionTe
*/ */
private long refreshTokenTime; private long refreshTokenTime;
private final OkHttpClient httpClient; private final CloseableHttpClient httpClient;
public WechatSubscriptionNotifier(NotifierProperties properties) { public WechatSubscriptionNotifier(NotifierProperties properties) {
this.properties = properties; this.properties = properties;
this.httpClient = new OkHttpClient.Builder().build(); this.httpClient = HttpClientBuilder.create().build();
} }
@Override @Override
@ -74,23 +89,21 @@ public class WechatSubscriptionNotifier implements Notifier<WechatSubscriptionTe
@Override @Override
public void send(WechatSubscriptionTemplate template, Map<String, Object> context) { public void send(WechatSubscriptionTemplate template, Map<String, Object> context) {
HttpUrl url = Objects.requireNonNull(HttpUrl.parse(notifyApi)).newBuilder()
.addQueryParameter("access_token", getToken())
.build();
Request request = new Request.Builder()
.url(url)
.header("Content-Type", "application/json; charset=UTF-8")
.post(RequestBody.create(template.createJsonRequest(), MediaType.get("application/json")))
.build();
try { try {
Call call = httpClient.newCall(request); URI sendMessageURI = new URIBuilder(notifyApi)
Response response = call.execute(); .addParameter("access_token", getToken())
JSONObject responseJson = JSON.parseObject(Objects.requireNonNull(response.body()).string()); .build();
HttpPost httpPost = new HttpPost(sendMessageURI);
httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
StringEntity requestBody = new StringEntity(template.createJsonRequest(), ContentType.APPLICATION_JSON);
httpPost.setEntity(requestBody);
CloseableHttpResponse response = httpClient.execute(httpPost);
JSONObject responseJson = JSON.parseObject(EntityUtils.toString(response.getEntity()));
System.out.println(responseJson); System.out.println(responseJson);
if (!responseJson.containsKey("errcode") || responseJson.getIntValue("errcode") != 0) { if (!responseJson.containsKey("errcode") || responseJson.getIntValue("errcode") != 0) {
throw new RuntimeException(responseJson.get("errmsg").toString()); throw new RuntimeException(responseJson.get("errmsg").toString());
} }
} catch (IOException e) { } catch (URISyntaxException | IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -99,6 +112,11 @@ public class WechatSubscriptionNotifier implements Notifier<WechatSubscriptionTe
public void close() { public void close() {
accessToken.set(null); accessToken.set(null);
refreshTokenTime = 0; refreshTokenTime = 0;
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
private String getToken() { private String getToken() {
@ -113,25 +131,22 @@ public class WechatSubscriptionNotifier implements Notifier<WechatSubscriptionTe
*/ */
private void refreshToken() { private void refreshToken() {
WechatSubscriptionProperties config = new JSONObject(properties.getConfiguration()).toJavaObject(WechatSubscriptionProperties.class); WechatSubscriptionProperties config = new JSONObject(properties.getConfiguration()).toJavaObject(WechatSubscriptionProperties.class);
HttpUrl url = HttpUrl.parse(tokenApi).newBuilder()
.addQueryParameter("grant_type", config.getGrantType())
.addQueryParameter("appid", config.getAppId())
.addQueryParameter("secret", config.getSecret())
.build();
Request request = new Request.Builder()
.url(url)
.get()
.build();
try { try {
Call call = httpClient.newCall(request); URI getTokenURI = new URIBuilder(tokenApi)
Response response = call.execute(); .addParameter("grant_type", config.getGrantType())
JSONObject responseJson = JSON.parseObject(Objects.requireNonNull(response.body()).string()); .addParameter("appid", config.getAppId())
.addParameter("secret", config.getSecret())
.build();
HttpGet httpGet = new HttpGet(getTokenURI);
CloseableHttpResponse response = httpClient.execute(httpGet);
String responseString = EntityUtils.toString(response.getEntity());
JSONObject responseJson = JSON.parseObject(responseString);
if (responseJson.containsKey("access_token")) { if (responseJson.containsKey("access_token")) {
accessToken.set(responseJson.get("access_token").toString()); accessToken.set(responseJson.get("access_token").toString());
} else if (responseJson.containsKey("errcode")) { } else if (responseJson.containsKey("errcode")) {
throw new RuntimeException(responseJson.get("errmsg").toString()); throw new RuntimeException(responseJson.get("errmsg").toString());
} }
} catch (IOException e) { } catch (URISyntaxException | IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -1,11 +1,13 @@
package com.simaek.notify.wechat.subscription; package com.cicdi.notify.wechat.subscription;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.template.TemplateProvider; import com.cicdi.notify.template.TemplateProvider;
import com.simaek.notify.wechat.WechatProvider; import com.cicdi.notify.wechat.WechatProvider;
import java.util.Map;
/** /**
* 微信公众号通知器提供商 * 微信公众号通知器提供商

View File

@ -1,6 +1,6 @@
package com.simaek.notify.wechat.subscription; package com.cicdi.notify.wechat.subscription;
import com.simaek.notify.NotifierProperties; import com.cicdi.notify.NotifierProperties;
/** /**
* 微信公众号通知器配置信息 * 微信公众号通知器配置信息

View File

@ -1,7 +1,7 @@
package com.simaek.notify.wechat.subscription; package com.cicdi.notify.wechat.subscription;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import java.util.Map; import java.util.Map;

View File

@ -1,13 +1,14 @@
package com.simaek.notify.wechat; package com.cicdi.notify.wechat;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.template.AbstractTemplateManager; import com.cicdi.notify.template.AbstractTemplateManager;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateManager; import com.cicdi.notify.template.TemplateManager;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.wechat.subscription.WechatSubscriptionNotifierProvider; import com.cicdi.notify.wechat.corp.WechatCorpNotifierProvider;
import com.cicdi.notify.wechat.subscription.WechatSubscriptionNotifierProvider;
import org.junit.Test; import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;

View File

@ -1,13 +1,13 @@
package com.simaek.notify.wechat; package com.cicdi.notify.wechat;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.simaek.notify.*; import com.cicdi.notify.*;
import com.simaek.notify.template.AbstractTemplateManager; import com.cicdi.notify.template.AbstractTemplateManager;
import com.simaek.notify.template.Template; import com.cicdi.notify.template.Template;
import com.simaek.notify.template.TemplateManager; import com.cicdi.notify.template.TemplateManager;
import com.simaek.notify.template.TemplateProperties; import com.cicdi.notify.template.TemplateProperties;
import com.simaek.notify.wechat.corp.WechatCorpNotifierProvider; import com.cicdi.notify.wechat.corp.WechatCorpNotifierProvider;
import com.simaek.notify.wechat.corp.WechatCorpTemplate; import com.cicdi.notify.wechat.corp.WechatCorpTemplate;
import org.junit.Test; import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;
@ -27,8 +27,8 @@ public class WechatTest {
notifierProperties.setId("12"); notifierProperties.setId("12");
Map<String, Object> config = new HashMap<>(); Map<String, Object> config = new HashMap<>();
config.put("corpId", "ww27a579a37932f608"); config.put("corpId", "wwbd49ae2419a55a9f");
config.put("corpSecret", "V3e3ore5zuiZmZZ1qYweebr6N1MFo37uGN4xoDwtnu8"); config.put("corpSecret", "TXDRQw_H8gpVKX0E01EmwMXJ4VooXmj65I-mDe0wQ1k");
notifierProperties.setConfiguration(config); notifierProperties.setConfiguration(config);
@ -44,8 +44,8 @@ public class WechatTest {
templateProperties.setProvider(WechatProvider.corpMessage.getId()); templateProperties.setProvider(WechatProvider.corpMessage.getId());
WechatCorpTemplate template = new WechatCorpTemplate(); WechatCorpTemplate template = new WechatCorpTemplate();
template.setAgentId("1000002"); template.setAgentId("3010084");
template.setToUser("Hsueh"); template.setToUser("XueYe");
template.setToParty(""); template.setToParty("");
template.setToTag(""); template.setToTag("");
template.setMessage("Hello"); template.setMessage("Hello");

106
pom.xml
View File

@ -4,10 +4,10 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.simaek</groupId> <groupId>com.cicdi</groupId>
<artifactId>notify-parent</artifactId> <artifactId>notify</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>0.1.1</version> <version>0.1.0</version>
<modules> <modules>
<module>notify-core</module> <module>notify-core</module>
<module>notify-email</module> <module>notify-email</module>
@ -25,44 +25,6 @@
<dependencies> <dependencies>
<dependency>
<groupId>com.simaek</groupId>
<artifactId>notify-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.simaek</groupId>
<artifactId>notify-dingtalk</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.simaek</groupId>
<artifactId>notify-email</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.simaek</groupId>
<artifactId>notify-sms</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.simaek</groupId>
<artifactId>notify-wechat</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>
@ -76,48 +38,18 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>4.5.13</version> <version>4.5.13</version>
</dependency> </dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.7</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -141,6 +73,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId> <artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration> <configuration>
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
</configuration> </configuration>
@ -149,6 +82,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration> <configuration>
<source>8</source> <source>8</source>
<target>8</target> <target>8</target>
@ -159,6 +93,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration> <configuration>
<skipTests>true</skipTests> <skipTests>true</skipTests>
</configuration> </configuration>
@ -184,6 +119,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<configuration> <configuration>
<attach>true</attach> <attach>true</attach>
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
@ -234,9 +170,9 @@
<developers> <developers>
<developer> <developer>
<name>Yaser Hsueh</name> <name>xueye</name>
<email>xueye404@qq.com</email>
<url>https://www.simaek.com</url> <url>https://www.simaek.com</url>
<email>master@simaek.com</email>
</developer> </developer>
</developers> </developers>
@ -244,15 +180,15 @@
<distributionManagement> <distributionManagement>
<repository> <repository>
<id>simaek-nexus</id> <id>nexus-bigdata-releases</id>
<name>release</name> <name>Cicdi Nexus Repository Release</name>
<url>https://nas.xueye.io:8081/repository/maven-releases/</url> <url>http://172.16.243.137:8081/repository/maven-releases/</url>
</repository> </repository>
<snapshotRepository> <snapshotRepository>
<id>simaek-nexus</id> <id>nexus-bigdata-snapshots</id>
<name>snapshots</name> <name>Bigdata Nexus Repository Snapshot</name>
<url>https://nas.xueye.io:8081/repository/maven-snapshots/</url> <url>http://172.16.243.137:8081/repository/maven-snapshots/</url>
</snapshotRepository> </snapshotRepository>
</distributionManagement> </distributionManagement>