Compare commits
No commits in common. "main" and "v0.1.0" have entirely different histories.
66
README.md
66
README.md
@ -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、使用预配置的模板发送信息(适用于定时提醒、验证码等较为常用的信息)
|
|
||||||
|
|
||||||
需要提供两个参数:notifierId,templateId。
|
|
||||||
|
|
||||||
```
|
|
||||||
// 通过配置信息的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模块中的接口即可。
|
|
@ -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>
|
||||||
|
@ -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;
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify;
|
package com.cicdi.notify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认支持的通知类型
|
* 默认支持的通知类型
|
@ -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;
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package com.simaek.notify;
|
package com.cicdi.notify;
|
||||||
|
|
||||||
import com.simaek.notify.template.Template;
|
import com.cicdi.notify.template.Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知器管理器,用于获取获取通知器
|
* 通知器管理器,用于获取获取通知器
|
@ -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;
|
@ -1,6 +1,6 @@
|
|||||||
package com.simaek.notify;
|
package com.cicdi.notify;
|
||||||
|
|
||||||
import com.simaek.notify.template.Template;
|
import com.cicdi.notify.template.Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知服务商
|
* 通知服务商
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify;
|
package com.cicdi.notify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知配置属性管理器,用于统一管理通知配置属性
|
* 通知配置属性管理器,用于统一管理通知配置属性
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify;
|
package com.cicdi.notify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知类型,通常使用枚举实现,枚举支持的通知类型
|
* 通知类型,通常使用枚举实现,枚举支持的通知类型
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify;
|
package com.cicdi.notify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务商标识,通常使用枚举实现,枚举支持的服务商
|
* 服务商标识,通常使用枚举实现,枚举支持的服务商
|
@ -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;
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知模板服务商
|
* 通知模板服务商
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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>
|
||||||
|
@ -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;
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify.dingtalk;
|
package com.cicdi.notify.dingtalk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 钉钉通知属性
|
* 钉钉通知属性
|
@ -1,6 +1,6 @@
|
|||||||
package com.simaek.notify.dingtalk;
|
package com.cicdi.notify.dingtalk;
|
||||||
|
|
||||||
import com.simaek.notify.Provider;
|
import com.cicdi.notify.Provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 钉钉通知提供商
|
* 钉钉通知提供商
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
||||||
|
|
@ -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>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.simaek.notify.email;
|
package com.cicdi.notify.email;
|
||||||
|
|
||||||
import com.simaek.notify.Provider;
|
import com.cicdi.notify.Provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邮件通知提供商
|
* 邮件通知提供商
|
@ -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;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify.email;
|
package com.cicdi.notify.email;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -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();
|
@ -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 {
|
||||||
|
|
@ -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;
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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() : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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
|
|
||||||
|
|
@ -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;
|
|
@ -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;
|
|
@ -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,7 +23,9 @@ public class DefaultEmailTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSend() {
|
public void testSend() {
|
||||||
// 通知器配置管理器
|
// 通知器配置管理器
|
||||||
NotifyConfigManager notifyConfigManager = (notifyType, configId) -> {
|
NotifyConfigManager notifyConfigManager = new NotifyConfigManager() {
|
||||||
|
@Override
|
||||||
|
public NotifierProperties getNotifyConfig(NotifyType notifyType, String configId) {
|
||||||
NotifierProperties notifierProperties = new NotifierProperties();
|
NotifierProperties notifierProperties = new NotifierProperties();
|
||||||
notifierProperties.setType(DefaultNotifyType.email.getId());
|
notifierProperties.setType(DefaultNotifyType.email.getId());
|
||||||
notifierProperties.setProvider(EmailProvider.embedded.getId());
|
notifierProperties.setProvider(EmailProvider.embedded.getId());
|
||||||
@ -45,6 +47,7 @@ public class DefaultEmailTest {
|
|||||||
config.put("properties", Arrays.asList(p1, p2));
|
config.put("properties", Arrays.asList(p1, p2));
|
||||||
notifierProperties.setConfiguration(config);
|
notifierProperties.setConfiguration(config);
|
||||||
return notifierProperties;
|
return notifierProperties;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 模板管理器
|
// 模板管理器
|
@ -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>
|
||||||
|
@ -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
|
@ -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;
|
@ -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;
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 阿里云短信通知服务
|
* 阿里云短信通知服务
|
@ -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;
|
||||||
|
|
@ -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,23 +56,21 @@ 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)) {
|
||||||
|
if (!"0".equals(resultMap.get(resultCodeKey)) && !"DELIVRD".equalsIgnoreCase(resultMap.get(resultCodeKey))) {
|
||||||
throw new RuntimeException("短信发送失败:" + resultMap.get("rspDesc"));
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify.sms.telecom;
|
package com.cicdi.notify.sms.telecom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云信通短信通知平台配置信息
|
* 云信通短信通知平台配置信息
|
@ -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
|
@ -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
|
@ -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;
|
@ -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));
|
||||||
|
|
@ -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>
|
@ -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("微信企业消息通知"),
|
@ -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;
|
@ -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;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.simaek.notify.wechat.corp;
|
package com.cicdi.notify.wechat.corp;
|
||||||
|
|
||||||
public class WechatCorpProperties {
|
public class WechatCorpProperties {
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信公众号通知器提供商
|
* 微信公众号通知器提供商
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信公众号通知器配置信息
|
* 微信公众号通知器配置信息
|
@ -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;
|
||||||
|
|
@ -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;
|
@ -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
106
pom.xml
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user