-
Notifications
You must be signed in to change notification settings - Fork 7.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from menethil/master
添加短信通知和邮件通知
- Loading branch information
Showing
13 changed files
with
524 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/ExecutorConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.linlinjava.litemall.core.notify; | ||
|
||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.scheduling.annotation.EnableAsync; | ||
import org.springframework.scheduling.annotation.EnableScheduling; | ||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||
|
||
import java.util.concurrent.Executor; | ||
import java.util.concurrent.ThreadPoolExecutor; | ||
|
||
/** | ||
* 异步线程池,用于异步发送通知 | ||
*/ | ||
@Configuration | ||
@EnableScheduling | ||
@EnableAsync | ||
class ExecutorConfig { | ||
|
||
@Value("${spring.notify.corePoolSize}") | ||
private int corePoolSize; | ||
@Value("${spring.notify.maxPoolSize}") | ||
private int maxPoolSize; | ||
@Value("${spring.notify.queueCapacity}") | ||
private int queueCapacity; | ||
|
||
@Bean(name = "nofityAsync") | ||
public Executor nofityAsync() { | ||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); | ||
executor.setCorePoolSize(corePoolSize); | ||
executor.setMaxPoolSize(maxPoolSize); | ||
executor.setQueueCapacity(queueCapacity); | ||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); | ||
executor.setThreadNamePrefix("NotifyExecutor-"); | ||
executor.initialize(); | ||
return executor; | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/LitemallNotifyService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package org.linlinjava.litemall.core.notify; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.PropertySource; | ||
import org.springframework.core.env.Environment; | ||
import org.springframework.stereotype.Service; | ||
|
||
/** | ||
* Litemall商城通知服务类 | ||
*/ | ||
@PropertySource(value = "classpath:notify.properties") | ||
@Service("litemallNotifyService") | ||
public class LitemallNotifyService { | ||
@Autowired | ||
MailSendService mailSendService; | ||
@Autowired | ||
SMSSendService smsSendService; | ||
@Autowired | ||
Environment environment; | ||
|
||
@Value("${sprint.mail.enable}") | ||
private boolean sendMailEnable; | ||
@Value("${spring.sms.enable}") | ||
private boolean sendSMSEnable; | ||
|
||
public void notifySMSMessage(String phoneNumber,String message) { | ||
if (!sendSMSEnable) | ||
return; | ||
|
||
smsSendService.sendSMS(phoneNumber, message); | ||
} | ||
|
||
/** | ||
* 短信模版通知 | ||
* @param phoneNumber 接收通知的电话号码 | ||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值 | ||
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID | ||
*/ | ||
public void notifySMSTemplate(String phoneNumber, String[] params, NotifyUtils.NotifyType notifyType) { | ||
if (!sendSMSEnable) | ||
return; | ||
|
||
int templateId = -1; | ||
switch (notifyType) { | ||
case PAY_COMPLATED: | ||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.pay.complated")); | ||
break; | ||
case VERIFICATIONCODE: | ||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.verificationcode")); | ||
break; | ||
} | ||
|
||
if (templateId != -1) | ||
smsSendService.sendSMSWithTemplate(phoneNumber, templateId, params); | ||
} | ||
|
||
/** | ||
* 发送邮件通知,接收者在spring.mail.sendto中指定 | ||
* @param setSubject 邮件标题 | ||
* @param setText 邮件内容 | ||
*/ | ||
public void notifyMailMessage(String setSubject, String setText) { | ||
if(!sendMailEnable) | ||
return; | ||
|
||
mailSendService.sendEmail(setSubject, setText); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/MailSendService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package org.linlinjava.litemall.core.notify; | ||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.PropertySource; | ||
import org.springframework.mail.javamail.JavaMailSender; | ||
import org.springframework.mail.javamail.MimeMessageHelper; | ||
import org.springframework.scheduling.annotation.Async; | ||
import org.springframework.stereotype.Service; | ||
|
||
import javax.annotation.Resource; | ||
import javax.mail.internet.MimeMessage; | ||
|
||
@PropertySource(value = "classpath:notify.properties") | ||
@Service("mailSendService") | ||
class MailSendService { | ||
@Resource | ||
private JavaMailSender mailSender; | ||
|
||
@Value("${spring.mail.username}") | ||
private String from; | ||
|
||
@Value("${spring.mail.sendto}") | ||
private String sendto; | ||
|
||
/** | ||
* 异步发送邮件通知 | ||
* @param setSubject 邮件标题 | ||
* @param setText 邮件内容 | ||
*/ | ||
@Async("nofityAsync") | ||
public void sendEmail(String setSubject, String setText) { | ||
try { | ||
final MimeMessage mimeMessage = mailSender.createMimeMessage(); | ||
final MimeMessageHelper message = new MimeMessageHelper(mimeMessage); | ||
|
||
message.setFrom(from); | ||
message.setTo(sendto); | ||
message.setSubject(setSubject); | ||
message.setText(setText); | ||
mailSender.send(mimeMessage); | ||
|
||
} catch (Exception ex) { | ||
|
||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.linlinjava.litemall.core.notify; | ||
|
||
public class NotifyUtils { | ||
/** | ||
* 该枚举定义了所有的需要通知的事件,调用通知时作为参数 | ||
*/ | ||
public enum NotifyType { | ||
PAY_COMPLATED, REGISTER, VERIFICATIONCODE, | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SMSSendService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package org.linlinjava.litemall.core.notify; | ||
|
||
import com.github.qcloudsms.SmsSingleSender; | ||
import com.github.qcloudsms.SmsSingleSenderResult; | ||
import com.github.qcloudsms.httpclient.HTTPException; | ||
import org.json.JSONException; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.PropertySource; | ||
import org.springframework.scheduling.annotation.Async; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.io.IOException; | ||
|
||
@PropertySource(value = "classpath:notify.properties") | ||
@Service("smsSendService") | ||
class SMSSendService { | ||
@Value("${spring.sms.appid}") | ||
private int appid; | ||
|
||
@Value("${spring.sms.appkey}") | ||
private String appkey; | ||
|
||
@Value("${spring.sms.sign}") | ||
private String smsSign; | ||
|
||
@Async("nofityAsync") | ||
public void sendSMS(String phoneNumber, String content) { | ||
try { | ||
SmsSingleSender ssender = new SmsSingleSender(appid, appkey); | ||
SmsSingleSenderResult result = ssender.send(0, "86", phoneNumber, | ||
content, "", ""); | ||
|
||
System.out.println(result); | ||
} catch (HTTPException e) { | ||
// HTTP响应码错误 | ||
e.printStackTrace(); | ||
} catch (JSONException e) { | ||
// json解析错误 | ||
e.printStackTrace(); | ||
} catch (IOException e) { | ||
// 网络IO错误 | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
@Async("nofityAsync") | ||
public void sendSMSWithTemplate(String phoneNumber, int templateId, String[] params) { | ||
try { | ||
SmsSingleSender ssender = new SmsSingleSender(appid, appkey); | ||
SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumber, | ||
templateId, params, smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信 | ||
System.out.println(result); | ||
} catch (HTTPException e) { | ||
// HTTP响应码错误 | ||
e.printStackTrace(); | ||
} catch (JSONException e) { | ||
// json解析错误 | ||
e.printStackTrace(); | ||
} catch (IOException e) { | ||
// 网络IO错误 | ||
e.printStackTrace(); | ||
} | ||
} | ||
} |
132 changes: 132 additions & 0 deletions
132
...mall-core/src/main/java/org/linlinjava/litemall/core/notify/WXTemplateMsgSendService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package org.linlinjava.litemall.core.notify; | ||
|
||
import org.json.JSONObject; | ||
import org.springframework.context.annotation.PropertySource; | ||
import org.springframework.stereotype.Service; | ||
|
||
import javax.net.ssl.*; | ||
import java.io.BufferedReader; | ||
import java.io.InputStream; | ||
import java.io.InputStreamReader; | ||
import java.io.OutputStream; | ||
import java.net.ConnectException; | ||
import java.net.URL; | ||
import java.security.SecureRandom; | ||
import java.security.cert.CertificateException; | ||
import java.security.cert.X509Certificate; | ||
|
||
/** | ||
* 微信模版消息通知,未完成 | ||
*/ | ||
@PropertySource(value = "classpath:notify.properties") | ||
@Service("wxTemplateMsgSendService") | ||
public class WXTemplateMsgSendService { | ||
/** | ||
* 发送微信消息(模板消息) | ||
* | ||
* @param touser 用户 OpenID | ||
* @param templatId 模板消息ID | ||
* @param formId payId或者表单ID | ||
* @param clickurl URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。 | ||
* @param topcolor 标题颜色 | ||
* @param data 详细内容 | ||
* @return | ||
*/ | ||
public String sendWechatMsgToUser(String token, String touser, String templatId, String formId, String clickurl, String topcolor, JSONObject data) { | ||
String tmpurl = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + token; | ||
JSONObject json = new JSONObject(); | ||
json.put("touser", touser); | ||
json.put("template_id", templatId); | ||
json.put("form_id", formId); | ||
json.put("url", clickurl); | ||
json.put("topcolor", topcolor); | ||
json.put("data", data); | ||
try { | ||
JSONObject result = httpsRequest(tmpurl, "POST", json.toString()); | ||
// log.info("发送微信消息返回信息:" + resultJson.get("errcode")); | ||
String errmsg = (String) result.get("errmsg"); | ||
if (!"ok".equals(errmsg)) { //如果为errmsg为ok,则代表发送成功,公众号推送信息给用户了。 | ||
return "error"; | ||
} | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
return "error"; | ||
} | ||
return "success"; | ||
} | ||
|
||
/** | ||
* 发送https请求 | ||
* | ||
* @param requestUrl 请求地址 | ||
* @param requestMethod 请求方式(GET、POST) | ||
* @param outputStr 提交的数据 | ||
* @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值) | ||
*/ | ||
private JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { | ||
JSONObject jsonObject = null; | ||
try { | ||
// 创建SSLContext对象,并使用我们指定的信任管理器初始化 | ||
TrustManager[] tm = {new MyX509TrustManager()}; | ||
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); | ||
sslContext.init(null, tm, new SecureRandom()); | ||
// 从上述SSLContext对象中得到SSLSocketFactory对象 | ||
SSLSocketFactory ssf = sslContext.getSocketFactory(); | ||
URL url = new URL(requestUrl); | ||
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); | ||
conn.setSSLSocketFactory(ssf); | ||
conn.setDoOutput(true); | ||
conn.setDoInput(true); | ||
conn.setUseCaches(false); | ||
// 设置请求方式(GET/POST) | ||
conn.setRequestMethod(requestMethod); | ||
// 当outputStr不为null时向输出流写数据 | ||
if (null != outputStr) { | ||
OutputStream outputStream = conn.getOutputStream(); | ||
// 注意编码格式 | ||
outputStream.write(outputStr.getBytes("UTF-8")); | ||
outputStream.close(); | ||
} | ||
// 从输入流读取返回内容 | ||
InputStream inputStream = conn.getInputStream(); | ||
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); | ||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); | ||
String str = null; | ||
StringBuffer buffer = new StringBuffer(); | ||
while ((str = bufferedReader.readLine()) != null) { | ||
buffer.append(str); | ||
} | ||
// 释放资源 | ||
bufferedReader.close(); | ||
inputStreamReader.close(); | ||
inputStream.close(); | ||
inputStream = null; | ||
conn.disconnect(); | ||
jsonObject = new JSONObject(buffer.toString()); | ||
} catch (ConnectException ce) { | ||
// log.error("连接超时:{}", ce); | ||
} catch (Exception e) { | ||
// log.error("https请求异常:{}", e); | ||
} | ||
return jsonObject; | ||
} | ||
|
||
/** | ||
* 微信请求 - 信任管理器 | ||
*/ | ||
private class MyX509TrustManager implements X509TrustManager { | ||
@Override | ||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { | ||
} | ||
|
||
@Override | ||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { | ||
} | ||
|
||
@Override | ||
public X509Certificate[] getAcceptedIssuers() { | ||
// return new X509Certificate[0]; | ||
return null; | ||
} | ||
} | ||
} |
Oops, something went wrong.