Skip to content

Commit

Permalink
Merge pull request #23 from menethil/master
Browse files Browse the repository at this point in the history
添加短信通知和邮件通知
  • Loading branch information
linlinjava authored Jul 14, 2018
2 parents d387431 + 18d9760 commit 03b4860
Show file tree
Hide file tree
Showing 13 changed files with 524 additions and 24 deletions.
16 changes: 15 additions & 1 deletion litemall-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,24 @@
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>

<dependency>
<groupId>com.github.qcloudsms</groupId>
<artifactId>qcloudsms</artifactId>
<version>1.0.5</version>
</dependency>
</dependencies>


<build>
<resources>
<resource>
Expand Down
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;
}
}
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);
}
}
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) {

}
}
}
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,
}
}
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();
}
}
}
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;
}
}
}
Loading

0 comments on commit 03b4860

Please sign in to comment.