工厂类的使用,不关心底层实现工具,外层只负责调用

编程

如题, 专做记录-虽然不太明白具体实现,以此做记录

设计结构

 

注意: 以下具体配置均已混淆, 实际使用请使用真实配置信息;

配置yml

litemall:

# 开发者应该设置成自己的wx相关信息

wx:

app-id: wx4d5ef10fb90757SS

app-secret: b8cc185ca92b311e0c8fee85c89062SS

mch-id: 1560901111

mch-key: 111111111111111111111111111111

notify-url: https://www.xxxx.vip/qdd/wx/order/pay-notify

# 商户证书文件路径

# 请参考“商户证书”一节 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3

key-path: xxxxx

#通知相关配置

notify:

mail:

# 邮件通知配置,邮箱一般用于接收业务通知例如收到新的订单,sendto 定义邮件接收者,通常为商城运营人员

enable: false

host: smtp.exmail.qq.com

username: ex@ex.com.cn

password: XXXXXXXXXXXXX

sendfrom: ex@ex.com.cn

sendto: ex@qq.com

# 短消息模版通知配置

# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值

sms:

enable: true

# 如果是腾讯云短信,则设置active的值tencent

# 如果是阿里云短信,则设置active的值aliyun

active: aliyun

tencent:

appid: 111111111

appkey: xxxxxxxxxxxxxx

aliyun:

regionId: cn-hangzhou

accessKeyId: LTAI4Fc5aio7M474NCfaXXX

accessKeySecret: KiqZzpQz3Mcl6xrfpFSj6Kd80bXXXX

sign: XX科技

template:

- name: paySucceed

templateId: 156300

- name: captcha

templateId: 156400

- name: ship

templateId: SMS_177552500

- name: refund

templateId: 159447

- name: reviewTimeOut

templateId: SMS_177547600

- name: reviewShip

templateId: SMS_177542600

- name: reviewSucceed

templateId: SMS_177537600

- name: payNotify

templateId: SMS_177537600

# 微信模版通知配置

# 微信模版用于通知客户或者运营者,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值

wx:

enable: false

template:

- name: paySucceed

templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

- name: captcha

templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

- name: ship

templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

- name: refund

templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

与配置映射的java类型

package org.linlinjava.litemall.core.notify.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

@ConfigurationProperties(prefix = "litemall.notify")

public class NotifyProperties {

private Mail mail;

private Sms sms;

private Wx wx;

public Mail getMail() {

return mail;

}

public void setMail(Mail mail) {

this.mail = mail;

}

public Sms getSms() {

return sms;

}

public void setSms(Sms sms) {

this.sms = sms;

}

public Wx getWx() {

return wx;

}

public void setWx(Wx wx) {

this.wx = wx;

}

public static class Mail {

private boolean enable;

private String host;

private String username;

private String password;

private String sendfrom;

private String sendto;

public boolean isEnable() {

return enable;

}

public void setEnable(boolean enable) {

this.enable = enable;

}

public String getHost() {

return host;

}

public void setHost(String host) {

this.host = host;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public String getSendfrom() {

return sendfrom;

}

public void setSendfrom(String sendfrom) {

this.sendfrom = sendfrom;

}

public String getSendto() {

return sendto;

}

public void setSendto(String sendto) {

this.sendto = sendto;

}

}

public static class Sms {

private boolean enable;

private String active;

private String sign;

private Tencent tencent;

private Aliyun aliyun;

private List<Map<String, String>> template = new ArrayList<>();

public boolean isEnable() {

return enable;

}

public void setEnable(boolean enable) {

this.enable = enable;

}

public List<Map<String, String>> getTemplate() {

return template;

}

public void setTemplate(List<Map<String, String>> template) {

this.template = template;

}

public String getActive() {

return active;

}

public void setActive(String active) {

this.active = active;

}

public String getSign() {

return sign;

}

public void setSign(String sign) {

this.sign = sign;

}

public Tencent getTencent() {

return tencent;

}

public void setTencent(Tencent tencent) {

this.tencent = tencent;

}

public Aliyun getAliyun() {

return aliyun;

}

public void setAliyun(Aliyun aliyun) {

this.aliyun = aliyun;

}

public static class Tencent {

private int appid;

private String appkey;

public int getAppid() {

return appid;

}

public void setAppid(int appid) {

this.appid = appid;

}

public String getAppkey() {

return appkey;

}

public void setAppkey(String appkey) {

this.appkey = appkey;

}

}

public static class Aliyun {

private String regionId;

private String accessKeyId;

private String accessKeySecret;

public String getRegionId() {

return regionId;

}

public void setRegionId(String regionId) {

this.regionId = regionId;

}

public String getAccessKeyId() {

return accessKeyId;

}

public void setAccessKeyId(String accessKeyId) {

this.accessKeyId = accessKeyId;

}

public String getAccessKeySecret() {

return accessKeySecret;

}

public void setAccessKeySecret(String accessKeySecret) {

this.accessKeySecret = accessKeySecret;

}

}

}

public static class Wx {

private boolean enable;

private List<Map<String, String>> template = new ArrayList<>();

public boolean isEnable() {

return enable;

}

public void setEnable(boolean enable) {

this.enable = enable;

}

public List<Map<String, String>> getTemplate() {

return template;

}

public void setTemplate(List<Map<String, String>> template) {

this.template = template;

}

}

}

读取配置的java 类

 

package org.linlinjava.litemall.core.notify.config;

import com.github.qcloudsms.SmsSingleSender;

import org.linlinjava.litemall.core.notify.AliyunSmsSender;

import org.linlinjava.litemall.core.notify.NotifyService;

import org.linlinjava.litemall.core.notify.TencentSmsSender;

import org.linlinjava.litemall.core.notify.WxTemplateSender;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.mail.javamail.JavaMailSender;

import org.springframework.mail.javamail.JavaMailSenderImpl;

@Configuration

@EnableConfigurationProperties(NotifyProperties.class)

public class NotifyAutoConfiguration {

private final NotifyProperties properties;

public NotifyAutoConfiguration(NotifyProperties properties) {

this.properties = properties;

}

@Bean

public NotifyService notifyService() {

NotifyService notifyService = new NotifyService();

NotifyProperties.Mail mailConfig = properties.getMail();

if (mailConfig.isEnable()) {

notifyService.setMailSender(mailSender());

notifyService.setSendFrom(mailConfig.getSendfrom());

notifyService.setSendTo(mailConfig.getSendto());

}

NotifyProperties.Sms smsConfig = properties.getSms();

if (smsConfig.isEnable()) {

if(smsConfig.getActive().equals("tencent")) {

notifyService.setSmsSender(tencentSmsSender());

}

else if(smsConfig.getActive().equals("aliyun")) {

notifyService.setSmsSender(aliyunSmsSender());

}

notifyService.setSmsTemplate(smsConfig.getTemplate());

}

NotifyProperties.Wx wxConfig = properties.getWx();

if (wxConfig.isEnable()) {

notifyService.setWxTemplateSender(wxTemplateSender());

notifyService.setWxTemplate(wxConfig.getTemplate());

}

return notifyService;

}

@Bean

public JavaMailSender mailSender() {

NotifyProperties.Mail mailConfig = properties.getMail();

JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

mailSender.setHost(mailConfig.getHost());

mailSender.setUsername(mailConfig.getUsername());

mailSender.setPassword(mailConfig.getPassword());

return mailSender;

}

@Bean

public WxTemplateSender wxTemplateSender() {

WxTemplateSender wxTemplateSender = new WxTemplateSender();

return wxTemplateSender;

}

@Bean

public TencentSmsSender tencentSmsSender() {

NotifyProperties.Sms smsConfig = properties.getSms();

TencentSmsSender smsSender = new TencentSmsSender();

NotifyProperties.Sms.Tencent tencent = smsConfig.getTencent();

smsSender.setSender(new SmsSingleSender(tencent.getAppid(), tencent.getAppkey()));

smsSender.setSign(smsConfig.getSign());

return smsSender;

}

@Bean

public AliyunSmsSender aliyunSmsSender() {

NotifyProperties.Sms smsConfig = properties.getSms();

AliyunSmsSender smsSender = new AliyunSmsSender();

NotifyProperties.Sms.Aliyun aliyun = smsConfig.getAliyun();

smsSender.setSign(smsConfig.getSign());

smsSender.setRegionId(aliyun.getRegionId());

smsSender.setAccessKeyId(aliyun.getAccessKeyId());

smsSender.setAccessKeySecret(aliyun.getAccessKeySecret());

return smsSender;

}

}

发送动作: 抽象java类

package org.linlinjava.litemall.core.notify;

public interface SmsSender {

/**

* 发送短信息

*

* @param phone 接收通知的电话号码

* @param content 短消息内容

*/

SmsResult send(String phone, String content);

/**

* 通过短信模版发送短信息

*

* @param phone 接收通知的电话号码

* @param templateId 通知模板ID

* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值

*/

SmsResult sendWithTemplate(String phone, String templateId, String[] params);

}

 

实际发送类: 腾讯短信, 阿里云短信....

package org.linlinjava.litemall.core.notify;

import com.github.qcloudsms.SmsSingleSender;

import com.github.qcloudsms.SmsSingleSenderResult;

import com.github.qcloudsms.httpclient.HTTPException;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

/*

* 腾讯云短信服务

*/

@Slf4j

public class TencentSmsSender implements SmsSender {

private SmsSingleSender sender;

private String sign;

public SmsSingleSender getSender() {

return sender;

}

public void setSender(SmsSingleSender sender) {

this.sender = sender;

}

@Override

public SmsResult send(String phone, String content) {

try {

SmsSingleSenderResult result = sender.send(0, "86", phone, content, "", "");

log.debug(result.toString());

SmsResult smsResult = new SmsResult();

smsResult.setSuccessful(true);

smsResult.setResult(result);

return smsResult;

} catch (HTTPException | IOException e) {

log.error(e.getMessage(), e);

}

SmsResult smsResult = new SmsResult();

smsResult.setSuccessful(false);

return smsResult;

}

@Override

public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {

try {

SmsSingleSenderResult result = sender.sendWithParam("86", phone, Integer.parseInt(templateId), params, this.sign, "", "");

log.debug(result.toString());

SmsResult smsResult = new SmsResult();

smsResult.setSuccessful(true);

smsResult.setResult(result);

return smsResult;

} catch (HTTPException | IOException e) {

log.error(e.getMessage(), e);

}

SmsResult smsResult = new SmsResult();

smsResult.setSuccessful(false);

return smsResult;

}

public void setSign(String sign) {

this.sign = sign;

}

}

package org.linlinjava.litemall.core.notify;

import com.aliyuncs.CommonRequest;

import com.aliyuncs.CommonResponse;

import com.aliyuncs.DefaultAcsClient;

import com.aliyuncs.IAcsClient;

import com.aliyuncs.exceptions.ClientException;

import com.aliyuncs.exceptions.ServerException;

import com.aliyuncs.http.MethodType;

import com.aliyuncs.profile.DefaultProfile;

import com.aliyuncs.profile.IClientProfile;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.exception.ExceptionUtils;

import org.linlinjava.litemall.core.util.JacksonUtil;

import java.util.HashMap;

import java.util.Map;

/*

* 阿里云短信服务

*/

@Slf4j

public class AliyunSmsSender implements SmsSender {

private String regionId;

private String accessKeyId;

private String accessKeySecret;

private String sign;

public String getRegionId() {

return regionId;

}

public void setRegionId(String regionId) {

this.regionId = regionId;

}

public String getAccessKeyId() {

return accessKeyId;

}

public void setAccessKeyId(String accessKeyId) {

this.accessKeyId = accessKeyId;

}

public String getAccessKeySecret() {

return accessKeySecret;

}

public void setAccessKeySecret(String accessKeySecret) {

this.accessKeySecret = accessKeySecret;

}

public String getSign() {

return sign;

}

public void setSign(String sign) {

this.sign = sign;

}

@Override

public SmsResult send(String phone, String content) {

SmsResult smsResult = new SmsResult();

smsResult.setSuccessful(false);

return smsResult;

}

@Override

public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {

IClientProfile profile = DefaultProfile.getProfile(this.regionId, this.accessKeyId, this.accessKeySecret);

IAcsClient client = null;

try{

client = new DefaultAcsClient(profile);

} catch (Exception e){

e.printStackTrace();

log.error("打印异常: "+ ExceptionUtils.getStackTrace(e));

}

CommonRequest request = new CommonRequest();

request.setMethod(MethodType.POST);

request.setDomain("dysmsapi.aliyuncs.com");

request.setVersion("2017-05-25");

request.setAction("SendSms");

request.putQueryParameter("RegionId", this.regionId);

request.putQueryParameter("PhoneNumbers", phone);

request.putQueryParameter("SignName", this.sign);

request.putQueryParameter("TemplateCode", templateId);

/*

NOTE:阿里云短信和腾讯云短信这里存在不一致

腾讯云短信模板参数是数组,因此短信模板形式如 “短信参数{1}, 短信参数{2}”

阿里云短信模板参数是JSON,因此短信模板形式如“短信参数{param1}, 短信参数{param2}”

为了保持统一,我们假定阿里云短信里面的参数是code,code1,code2...

如果开发者在阿里云短信申请的模板参数是其他命名,请开发者自行调整这里的代码,或者直接写死。

*/

String templateParam = "{}";

if(params.length == 1){

Map<String, String> data = new HashMap<>();

data.put("code", params[0]);

templateParam = JacksonUtil.toJson(data);

}

else if(params.length > 1){

Map<String, String> data = new HashMap<>();

data.put("code", params[0]);

for(int i = 1; i < params.length; i++){

data.put("code" + i, params[i]);

}

templateParam = JacksonUtil.toJson(data);

}

request.putQueryParameter("TemplateParam", templateParam);

try {

CommonResponse response = client.getCommonResponse(request);

SmsResult smsResult = new SmsResult();

smsResult.setSuccessful(true);

smsResult.setResult(response);

log.debug("发送成功: 发送结果:"+smsResult);

return smsResult;

} catch (ServerException e) {

e.printStackTrace();

} catch (ClientException e) {

e.printStackTrace();

}

SmsResult smsResult = new SmsResult();

smsResult.setSuccessful(false);

log.debug("发送失败: 发送结果:"+smsResult);

return smsResult;

}

}

package org.linlinjava.litemall.core.notify;

import cn.binarywang.wx.miniapp.api.WxMaService;

import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;

import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;

import lombok.extern.slf4j.Slf4j;

import org.linlinjava.litemall.db.domain.LitemallUserFormid;

import org.linlinjava.litemall.db.service.LitemallUserFormIdService;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;

import java.util.List;

/**

* 微信模版消息通知

*/

@Slf4j

public class WxTemplateSender {

@Autowired

private WxMaService wxMaService;

@Autowired

private LitemallUserFormIdService formIdService;

/**

* 发送微信消息(模板消息),不带跳转

*

* @param touser 用户 OpenID

* @param templatId 模板消息ID

* @param parms 详细内容

*/

public void sendWechatMsg(String touser, String templatId, String[] parms) {

sendMsg(touser, templatId, parms, "", "", "");

}

/**

* 发送微信消息(模板消息),带跳转

*

* @param touser 用户 OpenID

* @param templatId 模板消息ID

* @param parms 详细内容

* @param page 跳转页面

*/

public void sendWechatMsg(String touser, String templatId, String[] parms, String page) {

sendMsg(touser, templatId, parms, page, "", "");

}

private void sendMsg(String touser, String templatId, String[] parms, String page, String color,

String emphasisKeyword) {

LitemallUserFormid userFormid = formIdService.queryByOpenId(touser);

if (userFormid == null)

return;

WxMaTemplateMessage msg = new WxMaTemplateMessage();

msg.setTemplateId(templatId);

msg.setToUser(touser);

msg.setFormId(userFormid.getFormid());

msg.setPage(page);

msg.setColor(color);

msg.setEmphasisKeyword(emphasisKeyword);

msg.setData(createMsgData(parms));

try {

wxMaService.getMsgService().sendTemplateMsg(msg);

if (formIdService.updateUserFormId(userFormid) == 0) {

log.warn("更新数据已失效");

}

} catch (Exception e) {

log.error(e.getMessage(), e);

}

}

private List<WxMaTemplateData> createMsgData(String[] parms) {

List<WxMaTemplateData> dataList = new ArrayList<WxMaTemplateData>();

for (int i = 1; i <= parms.length; i++) {

dataList.add(new WxMaTemplateData("keyword" + i, parms[i - 1]));

}

return dataList;

}

}

其他: 枚举类型,返回结果等java类

package org.linlinjava.litemall.core.notify;

public enum NotifyType {

PAY_SUCCEED("paySucceed"), //支付成功通知

SHIP("ship"), // 发货通知

REFUND("refund"),

CAPTCHA("captcha"), // 小程序后台服务验证码不支持

PAY_TIMEOUT("payTimeOut"), //订单支付超时提醒

REVIEW_TIMEOUT("reviewTimeOut"), //评鉴超时提醒

REVIEW_SHIP("reviewShip"), //评鉴发货通知

REVIEW_SUCCEED("reviewSucceed"), //评鉴审核成功

PAY_NOTIFY("payNotify") // 支付成功通知

;

private String type;

NotifyType(String type) {

this.type = type;

}

public String getType() {

return this.type;

}

}

package org.linlinjava.litemall.core.notify;

/**

* 发送短信的返回结果

*/

public class SmsResult {

private boolean successful;

private Object result;

/**

* 短信是否发送成功

*

* @return

*/

public boolean isSuccessful() {

return successful;

}

public void setSuccessful(boolean successful) {

this.successful = successful;

}

public Object getResult() {

return result;

}

public void setResult(Object result) {

this.result = result;

}

}

 

发送测试类

package org.linlinjava.litemall.admin;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.linlinjava.litemall.core.notify.NotifyService;

import org.linlinjava.litemall.core.notify.NotifyType;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.core.env.Environment;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import org.springframework.test.context.web.WebAppConfiguration;

@WebAppConfiguration

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest

public class AdminConfigTest {

@Autowired

private Environment environment;

@Autowired

private NotifyService notifyService;

@Test

public void test() {

// 测试获取application-core.yml配置信息

System.out.println(environment.getProperty("litemall.express.appId"));

// 测试获取application-db.yml配置信息

System.out.println(environment.getProperty("spring.datasource.druid.url"));

// 测试获取application-admin.yml配置信息

// System.out.println(environment.getProperty(""));

// 测试获取application.yml配置信息

System.out.println(environment.getProperty("logging.level.org.linlinjava.litemall.admin"));

}

@Test

public void testSend() {

System.out.println("开始发送");

//TODO 发送邮件和短信通知,这里采用异步发送

// 发货会发送通知短信给用户: *

// "您的订单已经发货,快递公司 {1},快递单 {2} ,请注意查收"

notifyService.notifySmsTemplate("187581512XX", NotifyType.SHIP, new String[]{"STO", "3718162138269"});

System.out.println("结束发送");

}

}

 

 

 

 

 

以上是 工厂类的使用,不关心底层实现工具,外层只负责调用 的全部内容, 来源链接: utcz.com/z/511160.html

回到顶部