最近闲来无事,为了巩固一下知识点,写了一个利用JavaMail发送邮件的例子。只写了一个发送的例子,以后有时间再写下接收的例子。
1、简单介绍一下JavaMail的发送步骤
2、发送示例
首先,大家看下我的主程序。
package com.bao.main; import com.bao.entities.MailEntity; import com.bao.sendmail.SendMailHandler; public class Main { public static void main(String[] args) { MailEntity mailEntity = new MailEntity(); mailEntity.setSubject("设置邮件主题"); //主题 mailEntity.setToMails("[email protected]"); //接收人邮件地址 mailEntity.setFrom("[email protected]"); //发送人邮件地址 mailEntity.setContent("设置邮件内容"); //内容 //带附件的 // mailEntity.setContainAttach(true); //是否含有附件(true:有 false:无) // String[] aa = {"F:\\aaa.txt"}; //附件的路径(F:\\aaa.txt) // mailEntity.setArchives(aa); //将数组传入到实体的属性中 //不带附件 mailEntity.setContainAttach(false); SendMailHandler sendMailHandler = new SendMailHandler(); //发送邮件的方法类 sendMailHandler.sendMail(mailEntity); //发送 } }
从主程序可以看出,存在一个邮件实体MailEntity,还有一个邮件发送的方法类SendMailHandler 。发送的步骤就是创建一个邮件实体MailEntity,然后将其作为参数,利用SendMailHandler中的sendMail方法进行发送。
那好,下一步我们来看下实体MailEntity。
package com.bao.entities; /** * 发送邮件的Mail实体 */ public class MailEntity { private String mesId; //邮件id,预留字段 private String toMails; //收件人 private String copyMails; //抄送人 private String from; //发送人 private String content; //内容 private String[] archives; //上传附件路径 private String subject; //主题 private boolean containAttach; //是否带有附件 public String getMesId() { return mesId; } public void setMesId(String mesId) { this.mesId = mesId; } public String getCopyMails() { return copyMails; } public void setCopyMails(String copyMails) { this.copyMails = copyMails; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String[] getArchives() { return archives; } public void setArchives(String[] archives) { this.archives = archives; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public boolean isContainAttach() { return containAttach; } public void setContainAttach(boolean containAttach) { this.containAttach = containAttach; } public String getToMails() { return toMails; } public void setToMails(String toMails) { this.toMails = toMails; } }
只是一个实体bean,不做过多赘述。
然后看一下SendMailHandler方法类。
package com.bao.sendmail; import java.io.InputStream; import java.net.URL; import java.util.Date; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import com.bao.entities.MailEntity; import com.bao.util.MailUtil; import com.bao.util.UserAuthentication; /** * 发送邮件的实现类 */ public class SendMailHandler { private static Properties properties = System.getProperties(); Session sendMailSession = null; UserAuthentication authenticator = null; Transport trans = null; private void connect() throws Exception { //读取配置文件 URL url = MailUtil.findAsResource("mail.properties"); Properties props = new Properties(); InputStream ins; ins = url.openStream(); props.load(ins); //给properties赋值 properties.put("mail.smtp.host", props.getProperty("MAIL_SMTP_HOST")); properties.put("mail.smtp.port", props.getProperty("MAIL_SMTP_PORT")); properties.put("mail.smtp.auth", props.getProperty("MAIL_SMTP_AUTH")); if ("true".equals(props.getProperty("MAIL_SMTP_AUTH"))) { //是否需要进行安全验证 authenticator = new UserAuthentication(props.getProperty("MAIL_USER"),props.getProperty("MAIL_PWD")); } //根据邮件会话属性和密码验证器构造一个发送邮件的session会话 sendMailSession = Session.getDefaultInstance(properties,authenticator); //根据session会话,获得发送连接 trans = sendMailSession.getTransport("smtp"); trans.connect(props.getProperty("MAIL_SMTP_HOST"),props.getProperty("MAIL_USER"),props.getProperty("MAIL_PWD")); System.out.println("<<<<===============连接成功===============>>>>"); } /** * 发送邮件类 * @param 邮件实体 */ public boolean sendMail(MailEntity mail) { boolean flag = true; try { this.connect(); //连接邮件服务器操作 Message mailMessage = null; if(!mail.isContainAttach()) { mailMessage = getNormalMail(mail); } else { mailMessage = getArchivesMail(mail); } trans.send(mailMessage); System.out.println("<<<<===============发送成功===============>>>>"); } catch (Exception e) { flag = false; System.out.println("<<<<===============发送失败===============>>>>"); e.printStackTrace(); } finally { try { trans.close(); } catch (MessagingException e) { e.printStackTrace(); } } return flag; } /** * 生成简单邮件消息 * @param 邮件实体 */ private Message getNormalMail(MailEntity mail) throws Exception { //根据session创建一个邮件消息 Message mailMessage = new MimeMessage(sendMailSession); //设置邮件消息的发送者 mailMessage.setFrom(new InternetAddress(mail.getFrom())); //设置邮件的接收者地址 mailMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(mail.getToMails())); //设置邮件的主题 mailMessage.setSubject(mail.getSubject()); //设置邮件发送的时间 mailMessage.setSentDate(new Date()); //设置邮件的内容 mailMessage.setText(mail.getContent()); return mailMessage; } /** * 生成带附件的邮件消息 * @param 邮件实体 */ private Message getArchivesMail(MailEntity mail) throws Exception { Message mailMessage = new MimeMessage(sendMailSession); //设置邮件消息的发送者 mailMessage.setFrom(new InternetAddress(mail.getFrom())); //设置邮件的接收者地址 mailMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(mail.getToMails())); //设置邮件的主题 mailMessage.setSubject(mail.getSubject()); //设置邮件信息生成时间 mailMessage.setSentDate(new Date()); Multipart contentPart = new MimeMultipart(); //设置邮件内容 mailMessage.setContent(contentPart); //1 邮件文本内容 MimeBodyPart textPart = new MimeBodyPart(); textPart.setContent(mail.getContent(),"text/html; charset=GBK"); contentPart.addBodyPart(textPart);//将文本部分,添加到邮件内容 //2 附件 if(mail.getArchives() != null){ for(int i=0; i<mail.getArchives().length; i++){ MimeBodyPart archivePart = new MimeBodyPart(); //选择出每一个附件文件名 String filename = mail.getArchives()[i]; //得到数据源 FileDataSource fds = new FileDataSource(filename); //得到附件本身并至入BodyPart archivePart.setDataHandler(new DataHandler(fds)); //得到文件名同样至入BodyPart archivePart.setFileName(fds.getName()); // 将附件添加到附件集 contentPart.addBodyPart(archivePart); } } return mailMessage; } }
本类中有三个私有方法,和一个公共方法。对外部调用只提供了一个sendMail的方法。其余三个都是私有的方法。第一个connect方法的作用是根据javamail的Api进行与邮件服务器建立连接的过程。从而获得可以发送邮件的对象Transport 。第二和第三个私有方法是通过传入的邮件实体,构建Message的过程。一个是普通的邮件,一个带有附件的邮件。至于对外提供的公有方法sendMail,不做详细解释。
其中值得一提的是在连接方法中用到了俩个类,一个是使用授权者类,一个是MailUtil类。前者是JavaMail提供的类,后者是本文应用到一个邮件配置的文件,该类主要是读取邮件配置的工具方法。之所以将邮件配置写成一个properties文件,用意就是可以随时对邮件进行配置修改,不用重启程序。因为在每次连接的时候会自动读取一次properties文件。
下面将俩个应用类和配置文件提供给大家。
MailUtil类:
package com.bao.util; import java.net.URL; public class MailUtil{ /** * 获取文件完整路径的方法 * @param path 文件名称 * @return URL 文件完整路径 */ public static URL findAsResource(String path) { URL url = null; ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if (contextClassLoader != null) { url = contextClassLoader.getResource(path); } if (url != null) return url; url = MailUtil.class.getClassLoader().getResource(path); if (url != null) return url; url = ClassLoader.getSystemClassLoader().getResource(path); return url; } }
使用授权者类(UserAuthentication):
package com.bao.util; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; /** * 邮件用户安全验证的类 * @author Administrator */ public class UserAuthentication extends Authenticator { private String userName; private String password; public UserAuthentication(String userName, String password) { this.userName = userName; this.password = password; } public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password); } }
mail.properties:
MAIL_SMTP_HOST=smtp.163.com MAIL_SMTP_PORT=25 MAIL_SMTP_AUTH=true MAIL_USER= MAIL_PWD=
配置文件说明:前两个参数是主机和端口,第三个参数是是否进行授权验证,一般163,sohu邮箱都需要进行授权验证,否则连接不成功。第四个和第五个是发送人的用户名和密码。
3、说明
ps:附件为完整项目,和一份JavaMail的说明文档。