前言
最近在弄邮件相关的功能,被搞的头大,很多找的方法根本不知道该怎么往下走,就目前为止,
经过各种的碰壁和失败,就整理出来如何使用javamail实现邮件的接收、转发、发送、清除
不单单是分享,也为我后续查找更方便做一个记录
邮件相关概念
在正式发送邮件之前,我们应该对邮件有一个概念
第一点:
我觉得也是最重要的,接收和发送的主机host
和端口port
是不一样
的;我一开始的时候,并不懂;直接就不管是发送还是接收都用的一个主机host
和端口port
第二点:
接收邮件和发送邮件的协议不一样
,
发送邮件用的是SMTP
,SMTP 即简单邮件传输协议,用于邮件发送。SMTP 认证,简单地说就是要求必须提供账户名和密码
之后才可以登录 SMTP 服务器。
接收邮件用的是POP3
,
POP3协议允许电子邮件客户端下载服务器上的邮件,但是这个下载不会影响服务器本身的邮件
至于另外还有一个是IMAP
的协议,因为我这边并没有用到就不多说,感兴趣百度即可
导入依赖
用的是javamail,因此是需要导入javamail的maven依赖包
<!-- 邮件-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
邮件发送
public void sendMail(String toEmail, String ccEmail, String bccEmail, String subject, String text, List<File> files) {
try {
System.setProperty("mail.mime.splitlongparameters", "false");
final JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setUsername(username);
javaMailSender.setPassword(password);
javaMailSender.setHost(host);
javaMailSender.setPort(port);
javaMailSender.setProtocol(protocol);
javaMailSender.setDefaultEncoding(defaultEncoding);
final Properties mailProperties = new Properties();
mailProperties.put("mail.smtp.auth", true);
mailProperties.put("mail.smtp.starttls.enable", true);
javaMailSender.setJavaMailProperties(mailProperties);
final MimeMessage mimeMessage = getMimeMessage(toEmail, ccEmail, bccEmail, subject, text, javaMailSender, files,senderName);
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
System.out.println("发送邮件失败:"+e.getMessage());
}
}
private MimeMessage getMimeMessage(String toEmail, String ccEmail, String bccEmail, String subject, String text,
JavaMailSenderImpl javaMailSender, List<File> files,String senderName) throws javax.mail.MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
mimeMessageHelper.setFrom(senderName);
mimeMessageHelper.setTo(toEmail.split(","));
if (!Strings.isNullOrEmpty(ccEmail)) {
mimeMessageHelper.setCc(ccEmail.split(","));
}
if (!Strings.isNullOrEmpty(bccEmail)) {
mimeMessageHelper.setBcc(bccEmail.split(","));
}
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(text, true);
try {
if (!CollectionUtils.isEmpty(files)) {
for (File file : files) {
mimeMessageHelper.addAttachment(MimeUtility.encodeText(file.getName(), "GBK", "B"), file);
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return mimeMessage;
}
sendMail方法
我们在使用的时候直接调用sendMail方法即可
其中,各个参数含义如下:
toEmail:
发送到对应的邮箱
ccEmail:
抄送到对应的邮箱
bccEmail:
秘密抄送到对应邮箱
subject:
邮件主题
text:
字符文本,可以是html元素文本
files:
附件
在这个基础上,其实我们还是有额外的参数需要设置的,可以定义成全局
username:
用于发送邮件的邮箱账号
password:
用于发送邮件的邮箱密码
host:
发送邮件的主机
port:
发送邮件的端口
protocol:
发送邮件的协议,默认值是:smtp
defaultEncoding:
发送邮件的字符集,默认使用UTF-8
在这里,host和port是根据你需要连的邮箱进行设置的,比如连qq邮箱,网易邮箱。
百度能知道他们具体的协议和主机、端口
getMimeMessage方法
该方法其实主要就是将接收到的参数进行赋值发送邮箱,不需要多余讲解
邮件接收
public static Message[] receiveMail(String receiveHost,String receivePort,String receiveProtocol,String username,String password) throws Exception {
Properties props = new Properties();
props.put("mail.pop3.host", receiveHost);
props.put("mail.pop3.port", receivePort);
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
store = session.getStore(receiveProtocol);
// storeLocal.set(store);
store.connect();
folder = store.getFolder("INBOX");
// folderLocal.set(folder);
folder.open(Folder.READ_WRITE);
Calendar calendar = Calendar.getInstance();
// 搜索1天前到今天收到的的所有邮件,根据时间筛选邮件
calendar.add(Calendar.DAY_OF_MONTH, -1);
// 创建ReceivedDateTerm对象,ComparisonTerm.GE(大于等于),Date类型的时间 new Date(calendar.getTimeInMillis())----(表示1天前)
SentDateTerm term = new SentDateTerm(ComparisonTerm.GE, new Date(calendar.getTimeInMillis()));
Message[] messages = folder.search(term);
return messages;
}
receiveMail方法
以下为各个参数说明
receiveHost:
接收邮件的主机
receivePort:
接收邮件的端口
receiveProtocol:
接收邮件的协议,默认值:pop3
username:
需要接收邮件的账号
password:
需要接收邮件的密码
这里也是需要账号密码的,区别在于你需要查找接收对应邮箱有收到什么邮件,你就需要对应账号和密码才能接收到
其中,注释已经标注接收什么时间范围内的邮件
邮件转发
转发就有点意思,我找这个找遍了都没有对应的方法能够实现,现在我来说一下我是怎么样的一个思路
要想转发,第一步,你就得先接收邮件
但是接收完邮件,你不能把Folder
和Store
关闭掉
否则你是没有办法转发的
那什么是Folder和Store?
接收邮件和发送邮件很类似的都有用到Session,但是获取到Session后,我们需要从Session获取到特定类型的Store,然后连接到Store。
这里的Store代表了存储邮件的邮件服务器,在连接Store的过程中,我们是既有可能需要用到用户名和密码或者Authenticator,也就是验证的。
在连接到Store后,一个Folder对象,也叫目录对象,会通过Store的getFolder方法获取到邮件,也就能够从中读取到邮件。
这也是我们为什么想转发不能关闭他们的原因。
第二步,开始接收到需要转发的邮件,然后将对应邮件转发。
第三步,在转发完成之后我们才能够将其完成转发
也就是,我们必须接收邮件和转发邮件是同一个方法内进行的,没办法通过保存一个邮件类型的对象,额外做操作对其进行转发。
我也是卡死在了这一步上。
于是转发的方法如下:
public void forwardMail(String receiveHost,String receivePort,String username,String password,String sendHost,String sendPort,String SendFrom,String SendTo) {
//设置接收邮件
final Properties receiveProps = new Properties();
receiveProps.put("mail.pop3.host", receiveHost);
receiveProps.put("mail.pop3.port", receivePort);
final Session receiveSession = Session.getInstance(receiveProps, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
final ThreadLocal<Store> storeLocal = new ThreadLocal<>();
final Store store = receiveSession.getStore("pop3");
storeLocal.set(store);
store.connect();
final ThreadLocal<Folder> folderLocal = new ThreadLocal<>();
final Folder folder = store.getFolder("INBOX");
folderLocal.set(folder);
folder.open(Folder.READ_WRITE);
final Calendar calendar = Calendar.getInstance();
// 搜索所有邮件,根据时间筛选
calendar.add(Calendar.DAY_OF_MONTH, -10);//n天之内
// 创建ReceivedDateTerm对象,ComparisonTerm.GE(大于等于)
final SentDateTerm term = new SentDateTerm(ComparisonTerm.GE, new Date(calendar.getTimeInMillis()));
final Message[] messages = folder.search(term);
for (Message mail : messages) {
//String header = ((MimeMessage)mail).getHeader("SUBJECT")[0];
//log.info("Header:{}", header);
System.out.println("收到邮件的主题:", mail.getSubject());
if (mail.isMimeType("multipart/related")) {
final MimeMultipart mimeMultipart = (MimeMultipart) mail.getContent();
for (int i = 0; i < mimeMultipart.getCount(); i++) {
System.out.println("收到邮件的正文:", mimeMultipart.getBodyPart(i).getContent().toString().length());
}
}
System.out.println("--------------------------------分割线----------------------------------------");
//设置转发邮件
final Properties forwardProps = new Properties();
forwardProps.put("mail.smtp.host", sendHost);
forwardProps.put("mail.smtp.port", sendPort);
final Session forwardSession = Session.getInstance(forwardProps, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
// 创建转发邮件信息
final Message forwardMail = new MimeMessage(forwardSession);
// 设置主题
forwardMail.setSubject("转发: " + mail.getSubject());
forwardMail.setFrom(new InternetAddress(SendFrom));
forwardMail.addRecipient(Message.RecipientType.TO, new InternetAddress(SendTo));
//创建Multipart的容器
final Multipart multipart = new MimeMultipart();
//被转发的邮件体部分
final BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(mail.getDataHandler());
//添加到Multipart容器
multipart.addBodyPart(messageBodyPart);
forwardMail.setContent(multipart);
//发送
Transport.send(forwardMail);
}
folder.close(false);//false标识不删除读取的邮件
store.close();
}
receiveMail方法
以下为参数说明
receiveHost:
接收邮件的主机
receivePort:
接收邮件的端口
username:
接收邮件的账号
password:
接收邮件的密码
这里可以看到,我接收和转发用的都是一个username和password,表示我从接收的邮件的这个账号,用这个账号转发给别的邮箱
sendHost:
发送邮件的主机
sendPort:
发送邮件的端口
SendFrom:
从哪个邮箱进行转发
SendTo:
将邮件转发给该邮箱
清除邮箱
以时间为限制,删除一定时间内的邮件
public static void clearMail(String receiveHost,String receivePort,String receiveProtocol,String username,String password) throws Exception {
Properties props = new Properties();
props.put("mail.pop3.host", receiveHost);
props.put("mail.pop3.port", receivePort);
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
Store store = session.getStore(receiveProtocol);
// removeStoreLocal.set(store);
store.connect();
Folder folder = store.getFolder("INBOX");
// removeFolderLocal.set(folder);
folder.open(Folder.READ_WRITE);
Calendar calendar = Calendar.getInstance();
// 搜索7天前收到的的所有邮件,根据时间筛选邮件
calendar.add(Calendar.DAY_OF_MONTH, -7);
SentDateTerm term = new SentDateTerm(ComparisonTerm.LE, new Date(calendar.getTimeInMillis()));
Message[] messages = folder.search(term);
for (int i = 0; i < messages.length; i++) {
// if(!messages[i].getFolder().isOpen()) //判断是否open
// messages[i].getFolder().open(Folder.READ_WRITE);
messages[i].setFlag(Flags.Flag.DELETED, true);
}
folder.close(false);
store.close();
}
clearMail方法
以下为对应参数说明
receiveHost:
接收邮件的主机
receivePort:
接收邮件的端口
receiveProtocol:
接收邮件的协议
username:
接收该邮箱的邮件的账号
password:
接收该邮箱的邮件的密码
结语
以上,就是我通过springboot(java)使用javamail实现邮件的接收、转发、发送的具体过程,如后续有新内容将在本文章更新
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/101115.html