引言
我已经很久没有写过博客了,以前在博客园有写过一段时间,但后来因为工作的原因,没有更多的时间来写博客。这是我在51cto上的第一篇博文,写写JavaEmail发送邮件吧。
准备工作
下载好:javaMail.jar包和commons-lang-x.x.jar(后面附件中,我会把包一并送上,commons-lang因为在案例当中会用到)
案例介绍
演示了如何使用javaMail发送邮件
实践
首先,我们去新建一个web项目。我的项目名字就叫email.建好项目过后,在WebContent\WEB-INF\lib下加入上面介绍的两个包。给个图片:
然后添加一个config的源文件,用于放置配置文件,再到src源文件下添加一个包email。创那好过后,目录结构如下:
好了,现在已经万事俱备,只欠代码了。但是在写代码之前,我想,简单地对javaEmail作一点点介绍:
1.Java Mail是由Sun定义的一套收发电子邮件的API。
2.Java Mail服务程序可以有选择地实现某些邮件协议(smtp\pop3\imap),这三种协议都有对应SSL加密传输的协议,分别是SMTPS,POP3S和IMAPS
3.用于邮件处理的,分别有两个包:
mail. jar:此JAR文件包含 Java Mail API和Sun提供的SMTP、IMAP和POP3服务提供程序。
activation. jar:此JAR文件包含JAF API和Sun的实现。
4.javaMail的关键对象,包括:Properties、Session、Message、Authenticator、Address。
Properties对象里面主要是存放一些key-value,交给JavaMail识别如服务器地址、端口、用户名、密码等信息。
Properties对象,给定信息key列表:(例如:p.put("mail.smtp.port",25))
属性名 |
属性类别 |
说明 |
mail.stmp.host |
String |
SMTP服务器地址,如smtp.sina.com.cn |
mail.stmp.port |
int |
SMTP服务器端口号,默认为25 |
mail.stmp.auth |
boolean |
SMTP服务器是否需要用户认证,默认为false |
mail.stmp.from | String | 默认的邮件发送源地址 |
mail.stmp.socketFactory.class | String | socket工厂类类名,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.net.SocketFactory接口 |
mail.stmp.socketFactory.port | int | 指定socket工厂类所用的端口号,如果没有规定,则使用默认的端口号 |
mail.smtp.socketFactory.fallback | boolean | 设置为true时,当使用指定的socket类创建socket失败后,将使用java.net.Socket创建socket,默认为true |
mail.stmp.timeout | int | I/O连接超时时间,单位为毫秒,默认为永不超时 |
mail.stmp.user | String | SMTP默认的登陆用户名 |
Session对象
在javaEmail中,它表示与Email会话的对象,它需要通过Properties对象和认证者来初使化它。也就是说这个会话的产生,需要你做好相关Eail环境的配置。
Message对象主要是用于发送消息,和封装发送或接收信息。
Authenticator对象是指认证者,这个认证者主要需要两个东西,用户名和密码。一般我们会自定义一个认证者 extends Authenticator;然后new PasswordAuthentication(userName, password)给它。
关于javaMail的介绍先到这里。现在我们思考一个问题:发送邮件会有哪些对象?
这是我的假设:首先有一个邮件包(或电子邮件包)。这个邮件包,包括这些东西:1.这个邮件包是哪个机构发出来的(serverhost)2.这个机构的门牌号是什么(serverPort) 3.机构在发送这个包的时候,要不要对寄件人做身份验证。(isValidate) 4.寄件人身份信息是什么?(假设就是用户名和密码) 5.邮件包上应该有寄件人的地址。6.邮件包上应该有收件人的地址(如果是电子邮件,会有多个收件人,抄送等)7.这个邮件主要描述 8.这个邮件里装的什么东西。
好,现在根据上面的那些概念,我们先建一个EmailPackage对象如下:
package email; import java.io.InputStream; import java.util.Arrays; import java.util.Properties; import javax.mail.Address; import javax.mail.internet.InternetAddress; import org.apache.commons.lang.StringUtils; /** * 表示一个邮件包 * 此包中包括发送邮件的必备条件和邮件内容 * 暂时不支持附件的发送 如果后期需要,则加入属性 * 然后将附件加入到mutipart中即可 * @author 庄濮向 * */ public class EmailPackage { /* * 为你提供发送邮件的主机 * 比如对象:申通,圆通,或顺丰等机构 * 电子邮件对象比如:QQ,163的主机等 * like this:smtp.exmail.qq.com * */ private String serverHost; /* *发送邮件主机的端口 * */ private String serverPort; /* * 是否进行身份验证 * 如果进行验证,则需要您在该机构的用户名和密码 * */ private boolean isValidate; /* * 在该机构的用户名 * */ private String userName; /* * 在该机构的密码 */ private String password; /* * 发送方邮件地址 * 让接收者知道这个邮件是从哪里发过来的 */ private String fromAddress; /* * 接收方的邮件地址 * 多个主送 */ private Address[] mainSendAddresses; /* * 接收方的邮件地址 * 多个抄送 */ private Address[] copySendAddresses; /* * 发送的主题 * 可以理解为邮件的标题 */ private String subject; /* * 发送邮件的主要内容 * */ private StringBuilder content; /** * 构造函数 * 注:此包在构造的时候,将会从配置文件中获取除邮件内容以外的必备信息,就像一个清单 * 邮件内容可以自行放入 */ public EmailPackage(){ PasteBill(); } /** * 将发送内容一起加入包中 * @param content */ public EmailPackage(StringBuilder content){ PasteBill(); this.content=content; } /** * 为邮件包贴入清单 * 或者说是为发送邮件创建基础信息 * */ private void PasteBill(){ Properties p = new Properties(); InputStream in = EmailPackage.class.getClassLoader().getResourceAsStream("mail.properties"); try { p.load(in); this.serverHost = StringUtils.trim(p.getProperty("ServerHost")); this.serverPort = StringUtils.trim(p.getProperty("ServerPort")); if("true".equals(StringUtils.trim(p.getProperty("Validate")))){ this.isValidate = true; }else{ this.isValidate = false; } this.userName = StringUtils.trim(p.getProperty("UserName")); this.password = StringUtils.trim(p.getProperty("Password")); this.fromAddress = StringUtils.trim(p.getProperty("FromAddress")); String[] mainStr = StringUtils.trim(p.getProperty("MainSendAddresses")).split(","); //设置主送地址 this.mainSendAddresses = new InternetAddress[mainStr.length]; for(int i=0;i<mainStr.length;i++){ mainSendAddresses[i] = new InternetAddress(mainStr[i]); } //设置抄送地 String cc = StringUtils.trim(p.getProperty("CopySendAddresses")); if(!StringUtils.isEmpty(cc)){ String[] ccStr = cc.split(","); this.copySendAddresses = new InternetAddress[ccStr.length]; for(int i=0;i<ccStr.length;i++){ copySendAddresses[i]=new InternetAddress(ccStr[i]); } }else{ this.copySendAddresses = null; } this.subject = StringUtils.trim(p.getProperty("Subject")); } catch (Exception e) { e.printStackTrace(); } } //--------------setter and getter---------------------------------- public String getServerHost() { return serverHost; } public void setServerHost(String serverHost) { this.serverHost = serverHost; } public String getServerPort() { return serverPort; } public void setServerPort(String serverPort) { this.serverPort = serverPort; } public boolean isValidate() { return isValidate; } public void setValidate(boolean isValidate) { this.isValidate = isValidate; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFromAddress() { return fromAddress; } public void setFromAddress(String fromAddress) { this.fromAddress = fromAddress; } public Address[] getMainSendAddresses() { return mainSendAddresses; } public void setMainSendAddresses(Address[] mainSendAddresses) { this.mainSendAddresses = mainSendAddresses; } public Address[] getCopySendAddresses() { return copySendAddresses; } public void setCopySendAddresses(Address[] copySendAddresses) { this.copySendAddresses = copySendAddresses; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public StringBuilder getContent() { return content; } public void setContent(StringBuilder content) { this.content = content; } @Override public String toString() { return "EmailPackage [serverHost=" + serverHost + ", serverPort=" + serverPort + ", isValidate=" + isValidate + ", userName=" + userName + ", password=" + password + ", fromAddress=" + fromAddress + ", mainSendAddresses=" + Arrays.toString(mainSendAddresses) + ", copySendAddresses=" + Arrays.toString(copySendAddresses) + ", subject=" + subject + ", content=" + content + "]"; } public static void main(String[] args) { EmailPackage packages = new EmailPackage(); System.out.println(packages); } }
上述代码中,在初使化对象的时候有去执行PasteBill方法,而这个方法是去读取一个配置文件,那个这个配置文件里面存放了,这个属性需要的值,包括发送人,发送地址等信息,以后要更改,那么只需要改这个配置文件即可。新建文件mail.properties,放到config源文件下,配置文件内容如下:请根据提示做一定的更改
############################################# # the receive server host 你的服务机构的host ############################################# ServerHost=smtp.exmail.qq.com ############################################# # the receive server Port Default 25 ############################################# ServerPort=25 ############################################# # must validate the send user # you should send the true value ############################################# Validate=true ############################################# # send userName ############################################# [email protected] ############################################# # send user password ############################################# Password=请填写你的密码 ############################################# # send user EailAddress ############################################# [email protected] ############################################# # main send EailAddress # if have more like this:[email protected],[email protected] # you shoud use ',' to split ############################################# [email protected] ############################################# # copy send EailAddress # if have more like this:[email protected],[email protected] # you shoud use ',' to split ############################################# [email protected] ############################################# # set the defualt subject # you can change in you project. ############################################# Subject=这是你的主题内容
既然在发送邮件的过程中,会对人进行认证,那么我们就要去新建一个认证者,并且告诉它相关用户信息MyAuthenticator对象如下:
package email; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; public class MyAuthenticator extends Authenticator{ String userName = null; String password = null; public MyAuthenticator() { } public MyAuthenticator(String username, String password) { this.userName = username; this.password = password; } protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password); } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
接下来,思考这个邮件包,肯定是有一个邮件发送器来发的,那么在这个发送器,肯定要拥有这个邮件包,才可以。所以我们新建对象EmailSender:
package email; import java.util.Date; import java.util.Properties; import javax.mail.Address; import javax.mail.Authenticator; import javax.mail.BodyPart; import javax.mail.Message; 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; /** * 此类作为邮件的发送类 * 此类的使用必须要有一个EmailPackage包 * @author 庄濮向 * */ public class EmailSender { /* * 邮件包,包含了要发送的地址,信息等。 */ private EmailPackage emailPackage; /** * 要求必须要有一个包的传入 * @param emailPackage */ public EmailSender(EmailPackage emailPackage){ this.emailPackage = emailPackage; } /** * 执行发送的操作 * @return */ public boolean send(){ if(this.emailPackage!=null){ return sendMail(); }else{ return false; } } /** * 得到发送服务机构的综合信息 */ private Properties getServiceInfo(){ Properties p = new Properties(); p.put("mail.smtp.host", this.emailPackage.getServerHost()); p.put("mail.smtp.port", this.emailPackage.getServerPort()); p.put("mail.smtp.auth", this.emailPackage.isValidate() ? "true" : "false"); return p; } /** * 发送邮件 */ private boolean sendMail(){ Authenticator auth = null; if(this.emailPackage.isValidate()){ auth = new MyAuthenticator(emailPackage.getUserName(),emailPackage.getPassword()); } Session sessionConfig = Session.getDefaultInstance(getServiceInfo(), auth); Message message = new MimeMessage(sessionConfig); try { Address from = new InternetAddress(this.emailPackage.getFromAddress()); //来自哪里 message.setFrom(from); //主送哪些 message.setRecipients(Message.RecipientType.TO,this.emailPackage.getMainSendAddresses()); //抄送哪些 if(this.emailPackage.getCopySendAddresses()!=null){ message.addRecipients(Message.RecipientType.CC,this.emailPackage.getCopySendAddresses()); } //发送主题 message.setSubject(this.emailPackage.getSubject()); //发送的时间0 message.setSentDate(new Date()); //发送内容 //message.setText(this.emailPackage.getContent().toString()); //如果说是以html方式来发送,请用下面这个方法取代setText message.setContent(getMainpart()); //发送 Transport.send(message); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public EmailPackage getEmailPackage() { return emailPackage; } public void setEmailPackage(EmailPackage emailPackage) { this.emailPackage = emailPackage; } @SuppressWarnings("unused") private Multipart getMainpart(){ Multipart mainPart = new MimeMultipart(); try{ // 创建一个包含HTML内容的MimeBodyPart BodyPart html = new MimeBodyPart(); // 设置HTML内容 html.setContent(this.emailPackage.getContent().toString(), "text/html; charset=utf-8"); mainPart.addBodyPart(html); // 将MiniMultipart对象设置为邮件内容 }catch(Exception e){ e.printStackTrace(); } return mainPart; } }
写一个测试类EmailTest:
public class EmailTest { public static void main(String[] args) { StringBuilder content = new StringBuilder(); content.append("时间到了,自动发邮件,,我发。dd。。。我发.sdddsccccs.发发发"); boolean b = new EmailSender(new EmailPackage(content)).send(); if(!b){ System.out.println("发送子邮件不成功"); } } }
运行试试。