本文中的代码提供功能如下
1.发送普通邮件
2.发送带附件邮件
3.发送html邮件
4.处理未读邮件
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置类
@Configuration
@ConfigurationProperties(prefix = "email.config")
@Data
public class EmailConfig {
private String user;
private String password;
private String mailServerHost;
}
配置文件
email:
config:
user:
password:
mailServerHost:
以上配置文件须填写对应的配置,与配置类字段对应。
相关实体封装
查询邮件信息实体
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MailInfo {
private String subject;
private String from;
private String receiveAddress;
private Date sentDate;
private boolean isSeen;
private String priority;
private boolean isReplySign;
private int size;
private String msgId;
}
邮件信息实体构建类
public class MailInfoPackagingBuilder {
public MimeMessage msg;
public MailInfoPackagingBuilder(MimeMessage msg) {
this.msg = msg;
}
public MailInfo buildMailInfo() throws MessagingException, UnsupportedEncodingException {
return MailInfo
.builder()
.subject(getSubject())
.from(getFrom())
.receiveAddress(getReceiveAddress())
.sentDate(getSentDate())
.isSeen(isSeen())
.priority(getPriority())
.isReplySign(isReplySign())
.size(msg.getSize())
.msgId(this.msg.getMessageID())
.build();
}
/**
* 获得邮件主题
*
* @param msg 邮件内容
* @return 解码后的邮件主题
*/
private String getSubject() throws UnsupportedEncodingException, MessagingException {
return MimeUtility.decodeText(this.msg.getSubject());
}
/**
* 获得邮件发件人
*
* @param msg 邮件内容
* @return 姓名 <Email地址>
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
private String getFrom() throws MessagingException, UnsupportedEncodingException {
String from = "";
Address[] froms = this.msg.getFrom();
if (froms.length < 1)
throw new MessagingException("没有发件人!");
InternetAddress address = (InternetAddress) froms[0];
String person = address.getPersonal();
if (person != null) {
person = MimeUtility.decodeText(person) + " ";
} else {
person = "";
}
from = person + "<" + address.getAddress() + ">";
return from;
}
/**
* 根据收件人类型,获取邮件收件人、抄送和密送地址。如果收件人类型为空,则获得所有的收件人
* <p>Message.RecipientType.TO 收件人</p>
* <p>Message.RecipientType.CC 抄送</p>
* <p>Message.RecipientType.BCC 密送</p>
*
* @param msg 邮件内容
* @param type 收件人类型
* @return 收件人1 <邮件地址1>, 收件人2 <邮件地址2>, ...
* @throws MessagingException
*/
private String getReceiveAddress() throws MessagingException {
StringBuffer receiveAddress = new StringBuffer();
Address[] addresss = msg.getAllRecipients();
if (addresss == null || addresss.length < 1)
throw new MessagingException("没有收件人!");
for (Address address : addresss) {
InternetAddress internetAddress = (InternetAddress) address;
receiveAddress.append(internetAddress.toUnicodeString()).append(",");
}
receiveAddress.deleteCharAt(receiveAddress.length() - 1); //删除最后一个逗号
return receiveAddress.toString();
}
/**
* 获得邮件发送时间
*
* @param msg 邮件内容
* @return yyyy年mm月dd日 星期X HH:mm
* @throws MessagingException
*/
private Date getSentDate() throws MessagingException {
return msg.getSentDate();
}
/**
* 判断邮件中是否包含附件
*
* @return 邮件中存在附件返回true,不存在返回false
* @throws MessagingException
* @throws IOException
*/
private boolean isContainAttachment(Part part) throws MessagingException, IOException {
boolean flag = false;
if (part.isMimeType("multipart/*")) {
MimeMultipart multipart = (MimeMultipart) part.getContent();
int partCount = multipart.getCount();
for (int i = 0; i < partCount; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
String disp = bodyPart.getDisposition();
if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {
flag = true;
} else if (bodyPart.isMimeType("multipart/*")) {
flag = isContainAttachment(bodyPart);
} else {
String contentType = bodyPart.getContentType();
if (contentType.indexOf("application") != -1) {
flag = true;
}
if (contentType.indexOf("name") != -1) {
flag = true;
}
}
if (flag) break;
}
} else if (part.isMimeType("message/rfc822")) {
flag = isContainAttachment((Part) part.getContent());
}
return flag;
}
/**
* 判断邮件是否已读
*
* @param msg 邮件内容
* @return 如果邮件已读返回true, 否则返回false
* @throws MessagingException
*/
private boolean isSeen() throws MessagingException {
return msg.getFlags().contains(Flags.Flag.SEEN);
}
/**
* 判断邮件是否需要阅读回执
*
* @param msg 邮件内容
* @return 需要回执返回true, 否则返回false
* @throws MessagingException
*/
private boolean isReplySign() throws MessagingException {
boolean replySign = false;
String[] headers = msg.getHeader("Disposition-Notification-To");
if (headers != null)
replySign = true;
return replySign;
}
/**
* 获得邮件的优先级
*
* @param msg 邮件内容
* @return 1(High):紧急 3:普通(Normal) 5:低(Low)
* @throws MessagingException
*/
private String getPriority() throws MessagingException {
String priority = "普通";
String[] headers = msg.getHeader("X-Priority");
if (headers != null) {
String headerPriority = headers[0];
if (headerPriority.indexOf("1") != -1 || headerPriority.indexOf("High") != -1)
priority = "紧急";
else if (headerPriority.indexOf("5") != -1 || headerPriority.indexOf("Low") != -1)
priority = "低";
else
priority = "普通";
}
return priority;
}
/**
* 获得邮件文本内容
*
* @param part 邮件体
* @param content 存储邮件文本内容的字符串
* @throws MessagingException
* @throws IOException
*/
private void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {
//如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
if (part.isMimeType("text/*") && !isContainTextAttach) {
content.append(part.getContent().toString());
} else if (part.isMimeType("message/rfc822")) {
getMailTextContent((Part) part.getContent(), content);
} else if (part.isMimeType("multipart/*")) {
Multipart multipart = (Multipart) part.getContent();
int partCount = multipart.getCount();
for (int i = 0; i < partCount; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
getMailTextContent(bodyPart, content);
}
}
}
/**
* 文本解码
*
* @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本
* @return 解码后的文本
* @throws UnsupportedEncodingException
*/
private String decodeText(String encodeText) throws UnsupportedEncodingException {
if (encodeText == null || "".equals(encodeText)) {
return "";
} else {
return MimeUtility.decodeText(encodeText);
}
}
}
附件文件传递实体
@Data
@AllArgsConstructor
public class MultipartFileDto {
private byte[]bytes;
private String type;
private String filename;
}
邮件发送工具类
@Component
public class EmailHelper {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private EmailConfig emailConfig;
private static final Properties RECEIVE_PROPS = System.getProperties();
private static final Properties SEND_PROPS = System.getProperties();
static {
RECEIVE_PROPS.setProperty("mail.imap.auth", "true");
RECEIVE_PROPS.setProperty("mail.store.protocol", "imap");
RECEIVE_PROPS.setProperty("mail.imap.ssl.enable", "true");
RECEIVE_PROPS.setProperty("mail.imap.auth.login.disable", "true");
RECEIVE_PROPS.setProperty("mail.imap.usesocketchannels", "true");
}
static {
SEND_PROPS.setProperty("mail.host", "smtp.exmail.qq.com");
SEND_PROPS.setProperty("mail.transport.protocol", "smtp");
SEND_PROPS.setProperty("mail.smtp.auth", "true");
SEND_PROPS.setProperty("mail.smtp.ssl.enable", "true");
}
/**
* 发送邮件,附件可选
* @param subject
* @param text
* @param addressStr
* @param multipartFileDtos
* @throws MessagingException
*/
public void sendEmail( String subject,String text, List<String> addressStr,MultipartFileDto ... multipartFileDtos) throws MessagingException {
List<Address>addressList=new ArrayList<>();
for (String s : addressStr) {
Address address=new InternetAddress(s);
addressList.add(address);
}
Address[] addresses = addressList.toArray(new Address[0]);
this.sendEmail(subject,text, addresses,multipartFileDtos);
}
/**
* 发送网页邮件,附件可选
* @param subject
* @param html
* @param addressStr
* @param multipartFileDtos
* @throws MessagingException
*/
public void sendHtmlEmail(String subject, String html, List<String> addressStr, MultipartFileDto ... multipartFileDtos) throws MessagingException {
List<Address>addressList=new ArrayList<>();
for (String s : addressStr) {
Address address=new InternetAddress(s);
addressList.add(address);
}
Address[] addresses = addressList.toArray(new Address[0]);
this.sendHtmlEmail(subject, html, addresses,multipartFileDtos);
}
public void sendHtmlEmail(String subject, String html, Address[] addresses, MultipartFileDto ... multipartFileDtos) throws MessagingException {
Session session=Session.getInstance(SEND_PROPS);
//
Transport transport = session.getTransport();
transport.connect("smtp.exmail.qq.com", 465, emailConfig.getUser(), emailConfig.getPassword());
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(emailConfig.getUser()));
message.setRecipients(Message.RecipientType.TO,addresses);
message.setSubject(subject);
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setContent(html,"text/html;charset=UTF-8");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
for (MultipartFileDto multipartFileDto : multipartFileDtos) {
messageBodyPart = new MimeBodyPart();
DataSource source = new ByteArrayDataSource(multipartFileDto.getBytes(),multipartFileDto.getType());
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(multipartFileDto.getFilename());
multipart.addBodyPart(messageBodyPart);
}
// Put parts in message
message.setContent(multipart);
message.saveChanges();
// Send the message
transport.sendMessage(message,message.getAllRecipients());
}
/***
* 发送邮件功能
*/
public void sendEmail( String subject,String text, Address[] addresses,MultipartFileDto ... multipartFileDtos) throws MessagingException {
Session session=Session.getInstance(SEND_PROPS);
//
Transport transport = session.getTransport();
transport.connect("smtp.exmail.qq.com", 465, emailConfig.getUser(), emailConfig.getPassword());
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(emailConfig.getUser()));
message.setRecipients(Message.RecipientType.TO,addresses);
message.setSubject(subject);
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setText(text);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
for (MultipartFileDto multipartFileDto : multipartFileDtos) {
messageBodyPart = new MimeBodyPart();
DataSource source = new ByteArrayDataSource(multipartFileDto.getBytes(),multipartFileDto.getType());
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(multipartFileDto.getFilename());
multipart.addBodyPart(messageBodyPart);
}
// Put parts in message
message.setContent(multipart);
message.saveChanges();
// Send the message
transport.sendMessage(message,message.getAllRecipients());
}
/**
* 查询所有未读邮件
*
* @return
* @throws Exception
*/
public List<MailInfo> check() throws Exception {
List<MailInfo> result = new ArrayList<>();
Store store = this.initStore();
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_ONLY);
FlagTerm flagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
Message[] messages = folder.search(flagTerm);
for (int i = 0; i < messages.length; i++) {
MimeMessage msg = (MimeMessage) messages[i];
MailInfoPackagingBuilder mailInfoPackagingBuilder = new MailInfoPackagingBuilder(msg);
MailInfo mailInfo = mailInfoPackagingBuilder.buildMailInfo();
result.add(mailInfo);
}
folder.close(false);
store.close();
return result;
}
public void seenByMessageIds(Set<String> msgIds) throws MessagingException {
if (CollectionUtils.isEmpty(msgIds)) {
return;
}
Store store = this.initStore();
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_WRITE);
FlagTerm flagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
Message[] messages = folder.search(flagTerm);
logger.info("本次获取邮件共{}封", messages.length);
for (int i = 0; i < messages.length; i++) {
MimeMessage msg = (MimeMessage) messages[i];
//设置当前邮件状态为已读
if (msgIds.contains(msg.getMessageID())) {
logger.info("msgid seen,msgid:{}", msg.getMessageID());
msg.setFlag(Flags.Flag.SEEN, true);
}
}
folder.close(false);
store.close();
}
private Session initSession() throws MessagingException {
Session session=Session.getInstance(RECEIVE_PROPS);
return session;
}
private Store initStore() throws MessagingException {
Session session = this.initSession();
Store store = session.getStore("imap");
store.connect(emailConfig.getMailServerHost(), 993, emailConfig.getUser(), emailConfig.getPassword());
return store;
}
}
完整代码
完整的代码示例地址在gitee,地址如下,觉得不错的麻烦给个star

1659

被折叠的 条评论
为什么被折叠?



