修改邮件发送方式

master
bynt 1 year ago
parent d29def2798
commit 3c9c240397

@ -11,7 +11,9 @@ public class EncryptUtilsTest {
*/ */
@Test @Test
public void testDesEncrypt() { public void testDesEncrypt() {
try { try {
desEncrypt("baiye2022");
assertEquals("7772841DC6099402", desEncrypt("123456")); assertEquals("7772841DC6099402", desEncrypt("123456"));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
@Generated( @Generated(
value = "org.mapstruct.ap.MappingProcessor", value = "org.mapstruct.ap.MappingProcessor",
date = "2023-03-21T16:41:41+0800", date = "2023-05-29T13:21:00+0800",
comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_251 (Oracle Corporation)" comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_251 (Oracle Corporation)"
) )
@Component @Component

@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
@Generated( @Generated(
value = "org.mapstruct.ap.MappingProcessor", value = "org.mapstruct.ap.MappingProcessor",
date = "2023-03-21T16:41:41+0800", date = "2023-05-29T13:21:01+0800",
comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_251 (Oracle Corporation)" comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_251 (Oracle Corporation)"
) )
@Component @Component

@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhengjie.common.json.ApiDataResponse; import me.zhengjie.common.json.ApiDataResponse;
import me.zhengjie.constant.SystemConstant; import me.zhengjie.constant.SystemConstant;
import me.zhengjie.domain.EmailConfig;
import me.zhengjie.domain.vo.EmailVo; import me.zhengjie.domain.vo.EmailVo;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.dmpMonitor.domian.DmpMonitorNumDto; import me.zhengjie.modules.dmpMonitor.domian.DmpMonitorNumDto;
@ -23,6 +24,7 @@ import me.zhengjie.modules.dmpMonitor.dto.DataAnalysisRequestDTO;
import me.zhengjie.modules.uploadnew.service.impl.BuildPathUtils; import me.zhengjie.modules.uploadnew.service.impl.BuildPathUtils;
import me.zhengjie.service.EmailService; import me.zhengjie.service.EmailService;
import me.zhengjie.utils.FileUtil; import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.MailUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -81,7 +83,7 @@ public class StatisticsDmpServiceImpl implements StatisticsDmpService {
emailVo.setTos(list); emailVo.setTos(list);
emailVo.setSubject("一次性短链"); emailVo.setSubject("一次性短链");
emailVo.setContent(link); emailVo.setContent(link);
emailService.send(emailVo, emailService.find()); emailService.outlookMail(emailVo, emailService.find());
} }
private List<List<String>> getData(Map<String, Object> map) { private List<List<String>> getData(Map<String, Object> map) {

@ -1,6 +1,7 @@
package me.zhengjie; package me.zhengjie;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import me.zhengjie.domain.vo.EmailVo;
import me.zhengjie.modules.upload.domain.UploadFile; import me.zhengjie.modules.upload.domain.UploadFile;
import me.zhengjie.modules.upload.repository.UploadFileRepository; import me.zhengjie.modules.upload.repository.UploadFileRepository;
import me.zhengjie.modules.upload.service.UploadFileService; import me.zhengjie.modules.upload.service.UploadFileService;
@ -8,6 +9,7 @@ import me.zhengjie.modules.upload.service.dto.UploadFileDto;
import me.zhengjie.modules.upload.service.dto.UploadFileQueryCriteria; import me.zhengjie.modules.upload.service.dto.UploadFileQueryCriteria;
import me.zhengjie.modules.upload.service.mapstruct.UploadFileMapper; import me.zhengjie.modules.upload.service.mapstruct.UploadFileMapper;
import me.zhengjie.modules.upload.task.SaveToFileTask; import me.zhengjie.modules.upload.task.SaveToFileTask;
import me.zhengjie.service.EmailService;
import me.zhengjie.utils.PageUtil; import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp; import me.zhengjie.utils.QueryHelp;
import me.zhengjie.utils.SecurityUtils; import me.zhengjie.utils.SecurityUtils;
@ -21,6 +23,8 @@ import org.springframework.data.domain.Pageable;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ -37,6 +41,22 @@ public class SpringApplicationTest {
@Autowired @Autowired
private UploadFileService uploadFileService; private UploadFileService uploadFileService;
@Autowired
private EmailService emailService;
@Test
public void send(){
//发送邮件
EmailVo emailVo = new EmailVo();
List<String> list = new ArrayList<>();
list.add("lambda0821@outlook.com");
emailVo.setTos(list);
emailVo.setSubject("一次性短链");
emailVo.setContent("xxxx");
emailService.send(emailVo, emailService.find(2L));
}
/** /**
* *
*/ */

@ -119,7 +119,7 @@ public class TestEncryptInter {
@Test @Test
public void sendSms() { public void sendSms() {
Map<String, Object> map = new HashMap<>(2); Map<String, Object> map = new HashMap<>(2);
map.put("baseUrlAddr", "http://zw.juqianfw.com/"); map.put("baseUrlAddr", "https://cdn2.xjietiao.com/d/external_static/invite.html?mid=M6360640276240805889&eventCode=ACT_RICH_TOGETHER_EVENT");
ShortLinkUrlDto urlDto = JSONUtil.toBean(HttpUtil.post("s.z48.cn/trans", JSON.toJSONString(map)), ShortLinkUrlDto.class); ShortLinkUrlDto urlDto = JSONUtil.toBean(HttpUtil.post("s.z48.cn/trans", JSON.toJSONString(map)), ShortLinkUrlDto.class);
System.out.println(JSON.toJSONString(urlDto)); System.out.println(JSON.toJSONString(urlDto));
} }

@ -53,6 +53,6 @@ public class EmailConfig implements Serializable {
private String pass; private String pass;
@NotBlank @NotBlank
@ApiModelProperty(value = "收件人") @ApiModelProperty(value = "发件人地址")
private String fromUser; private String fromUser;
} }

@ -40,6 +40,12 @@ public interface EmailService {
*/ */
EmailConfig find(); EmailConfig find();
/**
* @param id
*
* @return EmailConfig
*/
EmailConfig find(Long id);
/** /**
* *
* @param emailVo * @param emailVo
@ -47,4 +53,11 @@ public interface EmailService {
* @throws Exception / * @throws Exception /
*/ */
void send(EmailVo emailVo, EmailConfig emailConfig); void send(EmailVo emailVo, EmailConfig emailConfig);
/**
* outlook
* @param emailVo
* @param emailConfig
*/
void outlookMail(EmailVo emailVo, EmailConfig emailConfig);
} }

@ -15,26 +15,31 @@
*/ */
package me.zhengjie.service.impl; package me.zhengjie.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.mail.Mail; import cn.hutool.extra.mail.Mail;
import cn.hutool.extra.mail.MailAccount; import cn.hutool.extra.mail.MailAccount;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.domain.EmailConfig; import me.zhengjie.domain.EmailConfig;
import me.zhengjie.domain.vo.EmailVo; import me.zhengjie.domain.vo.EmailVo;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.repository.EmailRepository; import me.zhengjie.repository.EmailRepository;
import me.zhengjie.service.EmailService; import me.zhengjie.service.EmailService;
import me.zhengjie.utils.EncryptUtils; import me.zhengjie.utils.EncryptUtils;
import me.zhengjie.utils.MailUtil;
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Optional; import java.util.Optional;
/** /**
* @author Zheng Jie * @author Zheng Jie
* @date 2018-12-26 * @date 2018-12-26
*/ */
@Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@CacheConfig(cacheNames = "email") @CacheConfig(cacheNames = "email")
@ -61,6 +66,12 @@ public class EmailServiceImpl implements EmailService {
return emailConfig.orElseGet(EmailConfig::new); return emailConfig.orElseGet(EmailConfig::new);
} }
@Override
public EmailConfig find(Long id) {
Optional<EmailConfig> emailConfig = emailRepository.findById(id);
return emailConfig.orElseGet(EmailConfig::new);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void send(EmailVo emailVo, EmailConfig emailConfig) { public void send(EmailVo emailVo, EmailConfig emailConfig) {
@ -69,7 +80,7 @@ public class EmailServiceImpl implements EmailService {
} }
// 封装 // 封装
MailAccount account = new MailAccount(); MailAccount account = new MailAccount();
account.setUser(emailConfig.getUser()); account.setDebug(true);
account.setHost(emailConfig.getHost()); account.setHost(emailConfig.getHost());
account.setPort(Integer.parseInt(emailConfig.getPort())); account.setPort(Integer.parseInt(emailConfig.getPort()));
account.setAuth(true); account.setAuth(true);
@ -81,23 +92,41 @@ public class EmailServiceImpl implements EmailService {
} }
account.setFrom(emailConfig.getUser() + "<" + emailConfig.getFromUser() + ">"); account.setFrom(emailConfig.getUser() + "<" + emailConfig.getFromUser() + ">");
// ssl方式发送 // ssl方式发送
account.setSslEnable(true); account.setSslEnable(false);
// 使用STARTTLS安全连接 // 使用STARTTLS安全连接
account.setStarttlsEnable(true); account.setStarttlsEnable(true);
String content = emailVo.getContent(); String content = emailVo.getContent();
// 发送 // 发送
try { try {
int size = emailVo.getTos().size(); int size = emailVo.getTos().size();
Mail.create(account) Mail.create(account).setTos(emailVo.getTos().toArray(new String[size])).setTitle(emailVo.getSubject()).setContent(content).setHtml(true)
.setTos(emailVo.getTos().toArray(new String[size]))
.setTitle(emailVo.getSubject())
.setContent(content)
.setHtml(true)
//关闭session //关闭session
.setUseGlobalSession(false) .setUseGlobalSession(false).send();
.send(); } catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
}
@Override
public void outlookMail(EmailVo emailVo, EmailConfig emailConfig) {
if (CollUtil.isNotEmpty(emailVo.getTos())) {
try {
for (String toAddress : emailVo.getTos()) {
int count = 0;
while (count < 3) {
boolean result = MailUtil.sendEmail(emailConfig.getFromUser(),
EncryptUtils.desDecrypt(emailConfig.getPass()),
emailConfig.getHost(), emailConfig.getPort(), toAddress, "一次性短链", emailVo.getContent());
log.info("===================== send mail result as {} =====================", result);
if (result) {
break;
}
count++;
}
}
} catch (Exception e) { } catch (Exception e) {
throw new BadRequestException(e.getMessage()); throw new BadRequestException(e.getMessage());
} }
} }
} }
}

@ -0,0 +1,246 @@
package me.zhengjie.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.exception.BadRequestException;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.*;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
* @author Enzo
* @date 2022-10-22 13:49:33
*/
@Slf4j
public class MailUtil {
private MailUtil() {
}
/**
*
*
* @param username
* @param password
* @return
*/
public static List<Message> readMailByIMAP(String username, String password) {
List<Message> list = Lists.newArrayList();
Properties props = System.getProperties();
//设置电子邮件协议
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect("outlook.office365.com", username, password);
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_WRITE);
Message[] messages = inbox.getMessages();
list.addAll(Arrays.asList(messages));
} catch (NoSuchProviderException e) {
log.error("======================= open mail error time {} message as {} ==================", DateUtil.date(), e.getMessage());
throw new BadRequestException("没有找到该服务");
} catch (MessagingException e) {
log.error("======================= open mail error time {} message as {} ==================", DateUtil.date(), e.getMessage());
throw new BadRequestException("发送邮件失败");
}
return list;
}
/**
* ++
*/
public static MimeMessage createMimeMessage(Session session, String sendMail, String receiveMail, String filename, String taskName) throws Exception {
// 1. 创建邮件对象
MimeMessage message = new MimeMessage(session);
// 2. From: 发件人
message.setFrom(new InternetAddress(sendMail, sendMail, CharsetUtil.UTF_8));
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
message.addRecipient(Message.RecipientType.TO, new InternetAddress(receiveMail, receiveMail, CharsetUtil.UTF_8));
// 4. Subject: 邮件主题
message.setSubject(taskName, CharsetUtil.UTF_8);
/*
* :
*/
// 6. 创建文本“节点”
/*MimeBodyPart text = new MimeBodyPart();
// 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
text.setContent(taskName, "text/html;charset=UTF-8");
// 7. (文本+图片)设置 文本 和 图片 “节点”的关系(将 文本 和 图片 “节点”合成一个混合“节点”)
MimeMultipart mmTextImage = new MimeMultipart();
mmTextImage.addBodyPart(text);
// 关联关系
mmTextImage.setSubType("related");
// 8. 将 文本+图片 的混合“节点”封装成一个普通“节点”
// 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
// 上面的 mm_text_image 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
MimeBodyPart textImage = new MimeBodyPart();
textImage.setContent(mmTextImage);*/
// 9. 创建附件“节点”
MimeBodyPart attachment = new MimeBodyPart();
// 读取本地文件
DataHandler dh2 = new DataHandler(new FileDataSource(filename));
// 将附件数据添加到“节点”
attachment.setDataHandler(dh2);
// 设置附件的文件名(需要编码)
attachment.setFileName(MimeUtility.encodeText(dh2.getName()));
// 10. 设置(文本+图片)和 附件 的关系(合成一个大的混合“节点” / Multipart
MimeMultipart mm = new MimeMultipart();
// mm.addBodyPart(textImage);
// 如果有多个附件,可以创建多个多次添加
mm.addBodyPart(attachment);
// 混合关系
mm.setSubType("mixed");
// 11. 设置整个邮件的关系(将最终的混合“节点”作为邮件的内容添加到邮件对象)
message.setContent(mm);
// 12. 设置发件时间
message.setSentDate(new Date());
// 13. 保存上面的所有设置
message.saveChanges();
return message;
}
public static Boolean sendMail(String username, String password, String toUsername, String fileName, String taskName) {
try {
// 1. 创建参数配置, 用于连接邮件服务器的参数配置
// 参数配置
Properties props = new Properties();
// 端口
props.put("mail.smtp.port", "587");
// 发件人的邮箱的 SMTP 服务器地址
props.put("mail.smtp.host", "smtp.office365.com");
// 当前smtp host设为可信任 否则抛出javax.mail.MessagingException: Could not convert socket to TLS
props.put("mail.smtp.ssl.trust", "smtp.office365.com");
// 使用的协议JavaMail规范要求
props.put("mail.transport.protocol", "smtp");
// 需要请求认证
props.put("mail.smtp.auth", "true");
// 开启STARTTLS
props.put("mail.smtp.starttls.enable", "true");
// ssl
props.put("mail.smtp.ssl", "true");
// 开启 SSL 连接, 以及更详细的发送步骤请看上一篇: 基于 JavaMail 的 Java 邮件发送:简单邮件发送
// 2. 根据配置创建会话对象, 用于和邮件服务器交互
Session session = Session.getInstance(props);
// 设置为debug模式, 可以查看详细的发送 log
session.setDebug(Boolean.FALSE);
// 3. 创建一封邮件
MimeMessage message = createMimeMessage(session, username, toUsername, fileName, taskName);
// 4. 根据 Session 获取邮件传输对象
Transport transport = session.getTransport();
// 5. 使用 邮箱账号 和 密码 连接邮件服务器
// 这里认证的邮箱必须与 message 中的发件人邮箱一致,否则报错
transport.connect(username, password);
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
// 7. 关闭连接
transport.close();
return Boolean.TRUE;
} catch (Exception ex) {
log.error("===================== send message error {} ==========================", ex.getMessage());
return Boolean.FALSE;
}
}
public static boolean sendEmail(String sender, String password, String host, String port, String receiver,String subject,String content) {
try {
Properties props = new Properties();
// 开启debug调试
props.setProperty("mail.debug", "false");
// 发送服务器需要身份验证
props.setProperty("mail.smtp.auth", "true");
// 设置邮件服务器主机名
props.setProperty("mail.host", host);
// 发送邮件协议名称 这里使用的是smtp协议
props.setProperty("mail.transport.protocol", "smtp");
// 服务端口号
props.setProperty("mail.smtp.port", port);
props.put("mail.smtp.starttls.enable", "true");
// 设置环境信息
Session session = Session.getInstance(props);
// 创建邮件对象
MimeMessage msg = new MimeMessage(session);
// 设置发件人
msg.setFrom(new InternetAddress(sender));
// 设置收件人
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(receiver));
// 设置邮件主题
msg.setSubject(subject);
// 设置邮件内容
Multipart multipart = new MimeMultipart();
MimeBodyPart textPart = new MimeBodyPart();
//发送邮件的文本内容
textPart.setText(content);
multipart.addBodyPart(textPart);
msg.setContent(multipart);
Transport transport = session.getTransport();
// 连接邮件服务器
transport.connect(sender, password);
// 发送邮件
transport.sendMessage(msg, new Address[]{new InternetAddress(receiver)});
// 关闭连接
transport.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
Loading…
Cancel
Save