java 中常用的邮件发送,此类的功能,一般为了优化代码,减少代码同步执行的压力,这类的功能都会做成异步发送,下面是 用mq实现的邮件发送的功能
这个功能是bpm调用的时候 审核通过的时候异步发送个邮件
@Override
public void updateLicenseStatus(UpdateLicenseStatusReq req) {
// 防止license多次更新 杨光 bpm
String businessDataKey = "businessDataKey::";
String msg = new String(JSON.toJSONString(req));
synchronized (req) {
String unique = req.getBusinessDataKey();
Integer status = req.getStatus();
if (ObjectUtils.isNotEmpty(unique)) {
if (redisTemplate.hasKey(businessDataKey + unique + status)) {
log.info("license状态已经更新,return:{}", unique);
return;
}
redisTemplate.opsForValue().set(businessDataKey + unique + status, msg, 3, TimeUnit.MINUTES);
}
}
log.info("【updateLicenseStatus】 req:{}", JSONUtil.toJsonPrettyStr(req));
ResponseMessage rsp = licenseFeign.editState(req);
log.info("【updateLicenseStatus】 rsp:{}", JSONUtil.toJsonPrettyStr(rsp));
//发送企微消息
if (Objects.nonNull(rsp.getData()) && !Objects.equals(ApproveStatusEnum.RECALL.getCode(), req.getStatus())) {
asyncExecuteService.executeAndCatchException("发送企微消息失败", () -> {
EditLicenseStateRsp stateRsp = rsp.getData();
String content = getLicenseContent(req.getStatus(), req.getInitiatorName(), stateRsp.getId(), stateRsp.getUseType());
weChatService.getErpChatRsp("license", content, req.getReceiverIds());
});
}
//发送邮件通知
if (Objects.equals(ApproveStatusEnum.APPROVED.getCode(), req.getStatus())&& Objects.nonNull(rsp.getData())) {
asyncExecuteService.executeAndCatchException("发送邮件失败", () -> {
Long licenseId = rsp.getData().getId();
LicenseDetailVO licenseDetailVO = service.queryLicenseDetail(licenseId);
Map userMap = userService.queryUserMap(Lists.newArrayList(licenseDetailVO.getCreateBy()));
String email = ObjectUtils.isEmpty(userMap.get(licenseDetailVO.getCreateBy())) ? null :userMap.get(licenseDetailVO.getCreateBy()).getEmail();
if (StringUtils.isNotEmpty(email)) {
List list = new ArrayList<>();
ExpireEmailVo expireEmailVo = new ExpireEmailVo();
expireEmailVo.setCustomerName(licenseDetailVO.getCustomerName());
expireEmailVo.setSendMail(email);
list.add(expireEmailVo);
EmailInfo emailInfo = new EmailInfo();
emailInfo.setDataRsps(list);
log.info("附件地址url : {}", getString(licenseId));
emailInfo.setFile(Lists.newArrayList(getString(licenseId)));
emailMessageService.noticeEmail(emailInfo);
}
});
}
}
逻辑层的调用
public Boolean noticeEmail(EmailInfo emailInfo) {
emailInfo.setContent(EmailEnum.MAIL_NOTICE.getContent());//邮件通知
emailInfo.setSubject(EmailEnum.MAIL_NOTICE.getSubject());
emailInfo.setId(IdWorker.getId());
RLock lock = redissonClient.getLock(CharSequenceUtil.format("noticeEmail#id::{}", emailInfo.getId()));
try {
if (lock.tryLock(3, 5, TimeUnit.SECONDS)) {
licenseMqProducer.publishNoticeMailEvent(emailInfo);
log.info("邮件发送成功 推 mq");
return true;
}
} catch (InterruptedException e) {
log.error("邮件发送失败, to: {}, title: {}", "to", "title", e);
return false;
} finally {
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return true;
}
mq生产
/**
* 推送邮件通知消息提醒
*
* @param msg 消息
*/
public void publishNoticeMailEvent(EmailInfo msg) {
log.info("邮件到期发送 publishMailEvent:{}", JSON.toJSONString(msg));
sendMsg(Constants.NOTICE_MAIL_EXCHANGE, Constants.NOTICE_MAIL_KEY, msg);
}
/**
* 推送消息的简单实现
*
* @param exchange exchange
* @param routingKey routingKey
* @param data 需要推送的消息
*/
public void sendMsg(@NonNull String exchange,
@NonNull String routingKey,
@Nullable Object data) {
String messageId = RandomUtil.randomNumbers(16);
log.info("准备发送消息,messageId:{} exchange:{} routingKey:{} data:{}", messageId, exchange, routingKey, data);
byte[] messageContent;
if (data == null) {
log.warn("数据为空不发送!");
return;
}
if (data instanceof CharSequence) {
messageContent = ((CharSequence) data).toString().getBytes();
} else {
messageContent = JSON.toJSONString(data).getBytes();
}
MessageProperties messageProperties = new MessageProperties();
messageProperties.setMessageId(messageId);
Message message = new Message(messageContent, messageProperties);
rabbitTemplate.convertAndSend(exchange, routingKey, message);
log.info("消息发送成功,messageId:{}", messageId);
}
mq消费
@RabbitListener(bindings = @QueueBinding(value = @Queue("noticeEmail"),
exchange = @Exchange(value = Constants.NOTICE_MAIL_EXCHANGE,
type = ExchangeTypes.TOPIC), key = Constants.NOTICE_MAIL_KEY))
public void listenerAlexanderMessage(Message message, Channel channel) throws IOException {
String msg = "";
MsgLog vo =null;
try {
msg = new String(message.getBody());
String messageId = message.getMessageProperties().getMessageId();
EmailInfo data = JSONObject.parseObject(msg, EmailInfo.class);
for (ExpireEmailVo toUser : data.getDataRsps()){
this.sendMesssage(toUser.getSendMail(), toUser.getCustomerName(), toUser.getExpirationDate(), data.getContent(), data.getSubject(), data.getFile());
}
vo = new MsgLog();
vo.setId(IdWorker.getId());
vo.setMsg(JSON.toJSONString(msg));
vo.setMsgId(messageId);
vo.setAccountId(data.getAccountId());
vo.setStatus(1);
vo.setRoutingKey(Constants.NOTICE_MAIL_KEY);
vo.setExchange(Constants.NOTICE_MAIL_EXCHANGE);
msgLogMapper.insert(vo);
String redisMessageKey = "noticeMail_messageId::";
synchronized (this) {
if (ObjectUtils.isNotEmpty(messageId)) {
if (redisTemplate.hasKey(redisMessageKey + messageId)) {
log.info("消息id已消费,return:{}", messageId);
return;
}
redisTemplate.opsForValue().set(redisMessageKey + messageId, msg, 2, TimeUnit.DAYS);
}
}
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception exception) {
log.error("邮件通知参数 错误~~~~~~~~~~~~~~~~~{}", JSONUtil.toJsonStr(exception));
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
if (vo != null) {
vo.setId(IdWorker.getId());
vo.setStatus(2);
vo.setMsgId(message.getMessageProperties().getMessageId());
vo.setRemark(exception.getMessage());
msgLogMapper.insert(vo);
log.error("邮件通知参数-》操作邮件通知 失败记录日志");
}
}
log.info("邮件通知执行 End");
}
mq辅助邮件发送
public Boolean sendMesssage(String to, String customerName,String expirationDate, String content, String title, List attachments){
SendEmailInfo sendEmailInfo = new SendEmailInfo();
sendEmailInfo.setEmail(to);
sendEmailInfo.setFiles(attachments);
sendEmailInfo.setSubject(String.format(title, ObjectUtils.isEmpty(customerName) ? "" : "客户:"+ customerName +"," ));
sendEmailInfo.setEmailContent(String.format(content, ObjectUtils.isEmpty(customerName) ? "" : "客户:"+ customerName +"," , expirationDate));
getErpUrlRsp(emailUrl, sendEmailInfo);
return true;
}
/**
* 调用erp企微服务
* @param url 请求地址
* @param obj 请求参数
* @return
*/
private JSONObject getErpUrlRsp(String url, Object obj) {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json;charset=UTF-8");
String objStr = JSON.toJSONString(obj);
HttpEntity
至此,异步邮件发送通知结束