javamail实现发送邮件并简单实现观察者模式
2015-09-22 18:41
543 查看
最近项目中要用到邮件发送,所以今天上网搜了下相关技术文档,发现其中一篇文章被转了N次,但是其中有缺失的部分,看了下评论,可能有部分新手不知道怎么补齐,自己学习之余补齐了缺失部分,整理出来,供大家参考。
JAVA MAIL是利用现有的邮件账户发送邮件的工具,比如说,我在网易注册一个邮箱账户,通过JAVA Mail的操控,我可以不亲自登录网易邮箱,让程序自动的使用网易邮箱发送邮件。这一机制被广泛的用在注册激活和垃圾邮件的发送等方面。
JavaMail可以到http://www.oracle.com/technetwork/java/javamail/index-138643.html进行下载,并将mail.jar添加到classpath即可。如果你使用的是JAVA EE SDK,则可以在C:\glassfishv3\glassfish\modules\mail.jar找到所需的jar包,同样需要添加的classpath。
JAVA邮件发送的大致过程是这样的的:
1、构建一个继承自javax.mail.Authenticator的具体类,并重写里面的getPasswordAuthentication()方法。此类是用作登录校验的,以确保你对该邮箱有发送邮件的权利。
2、构建一个properties文件,该文件中存放SMTP服务器地址等参数。
3、通过构建的properties文件和javax.mail.Authenticator具体类来创建一个javax.mail.Session。Session的创建,就相当于登录邮箱一样。剩下的自然就是新建邮件。
4、构建邮件内容,一般是javax.mail.internet.MimeMessage对象,并指定发送人,收信人,主题,内容等等。
5、使用javax.mail.Transport工具类发送邮件。
下面部分代码是从转载文章处copy下来的,部分是自己补齐的:
1、首先是继承自javax.mail.Authenticator的一个具体类。getPasswordAuthentication()方法也就是构建一个PasswordAuthentication对象并返回,有点费解JAVA Mail这样的设计意图,可能是javax.mail.Authenticator为我们提供了附加的保证安全的验证措施吧。
2、邮件发送类,剩下的步骤都是在这个类实现的。代码中的SimpleMail是封装了邮件主题和内容的一个POJO。觉得在一个方法参数中既包含主题又包含内容,不太合适,故重载了此方法。还有就是因为大多数邮箱的SMTP服务器地址都是可以通过邮箱地址算出来,简单起见,提供了一个不需要SMTP服务器地址的构造器。
SimpleMail.java类(缺失部分)
3、调用上面的邮箱发送器,可以构建一个工厂类,工厂类可以封装创建的过程,所以通过读配置文件获取邮箱用户名,密码都会变得十分方便。下面的代码是我在写观察者模式的时候写的,只是简单演示了工厂类。
MailSenderType.java(缺失部分)
4、发送邮件,还是观察者模式DEMO里面的代码,呼呼。
Product.java(缺失部分)
5,最后测试类
最后附上源码下载地址(免费):http://download.csdn.net/download/osaymissyou0/9131033
补充 javamail Session中Properties属性表:
Session需要使用java.util.Properties来构造,常用的用来构造Session的属性:
JAVA MAIL是利用现有的邮件账户发送邮件的工具,比如说,我在网易注册一个邮箱账户,通过JAVA Mail的操控,我可以不亲自登录网易邮箱,让程序自动的使用网易邮箱发送邮件。这一机制被广泛的用在注册激活和垃圾邮件的发送等方面。
JavaMail可以到http://www.oracle.com/technetwork/java/javamail/index-138643.html进行下载,并将mail.jar添加到classpath即可。如果你使用的是JAVA EE SDK,则可以在C:\glassfishv3\glassfish\modules\mail.jar找到所需的jar包,同样需要添加的classpath。
JAVA邮件发送的大致过程是这样的的:
1、构建一个继承自javax.mail.Authenticator的具体类,并重写里面的getPasswordAuthentication()方法。此类是用作登录校验的,以确保你对该邮箱有发送邮件的权利。
2、构建一个properties文件,该文件中存放SMTP服务器地址等参数。
3、通过构建的properties文件和javax.mail.Authenticator具体类来创建一个javax.mail.Session。Session的创建,就相当于登录邮箱一样。剩下的自然就是新建邮件。
4、构建邮件内容,一般是javax.mail.internet.MimeMessage对象,并指定发送人,收信人,主题,内容等等。
5、使用javax.mail.Transport工具类发送邮件。
下面部分代码是从转载文章处copy下来的,部分是自己补齐的:
1、首先是继承自javax.mail.Authenticator的一个具体类。getPasswordAuthentication()方法也就是构建一个PasswordAuthentication对象并返回,有点费解JAVA Mail这样的设计意图,可能是javax.mail.Authenticator为我们提供了附加的保证安全的验证措施吧。
/** * */ package com.study.mail; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; /** * 服务器邮箱登录验证 * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public class MailAuthenticator extends Authenticator { /** * 用户名(登录邮箱) */ private String username; /** * 密码 */ private String password; /** * 初始化邮箱和密码 * * @param username * 邮箱 * @param password * 密码 */ public MailAuthenticator(String username, String password) { this.username = username; this.password = password; } String getPassword() { return password; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } String getUsername() { return username; } public void setPassword(String password) { this.password = password; } public void setUsername(String username) { this.username = username; } }
2、邮件发送类,剩下的步骤都是在这个类实现的。代码中的SimpleMail是封装了邮件主题和内容的一个POJO。觉得在一个方法参数中既包含主题又包含内容,不太合适,故重载了此方法。还有就是因为大多数邮箱的SMTP服务器地址都是可以通过邮箱地址算出来,简单起见,提供了一个不需要SMTP服务器地址的构造器。
/** * */ package com.study.mail; import java.util.List; import java.util.Properties; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; /** * * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public class SimpleMailSender { /** * 发送邮件的props文件 */ private final transient Properties props = System.getProperties(); /** * 邮件服务器登录验证 */ private transient MailAuthenticator authenticator; /** * 邮箱session */ private transient Session session; /** * 初始化邮件发送器 * * @param smtpHostName * SMTP邮件服务器地址 * @param username * 发送邮件的用户名(地址) * @param password * 发送邮件的密码 */ public SimpleMailSender(final String smtpHostName, final String username, final String password) { init(username, password, smtpHostName); } /** * 初始化邮件发送器 * * @param username * 发送邮件的用户名(地址),并以此解析SMTP服务器地址 * @param password * 发送邮件的密码 */ public SimpleMailSender(final String username, final String password) { //通过邮箱地址解析出smtp服务器,对大多数邮箱都管用 final String smtpHostName = "smtp." + username.split("@")[1]; init(username, password, smtpHostName); } /** * 初始化 * * @param username * 发送邮件的用户名(地址) * @param password * 密码 * @param smtpHostName * SMTP主机地址 */ private void init(String username, String password, String smtpHostName) { // 初始化props props.put("mail.smtp.auth", "true"); props.put("mail.smtp.host", smtpHostName); // 验证 authenticator = new MailAuthenticator(username, password); // 创建session session = Session.getInstance(props, authenticator); } /** * 发送邮件 * * @param recipient * 收件人邮箱地址 * @param subject * 邮件主题 * @param content * 邮件内容 * @throws AddressException * @throws MessagingException */ public void send(String recipient, String subject, Object content) throws AddressException, MessagingException { // 创建mime类型邮件 final MimeMessage message = new MimeMessage(session); // 设置发信人 message.setFrom(new InternetAddress(authenticator.getUsername())); // 设置收件人 message.setRecipient(RecipientType.TO, new InternetAddress(recipient)); // 设置主题 message.setSubject(subject); // 设置邮件内容 message.setContent(content.toString(), "text/html;charset=utf-8"); // 发送 Transport.send(message); } /** * 群发邮件 * * @param recipients * 收件人们 * @param subject * 主题 * @param content * 内容 * @throws AddressException * @throws MessagingException */ public void send(List<String> recipients, String subject, Object content) throws AddressException, MessagingException { // 创建mime类型邮件 final MimeMessage message = new MimeMessage(session); // 设置发信人 message.setFrom(new InternetAddress(authenticator.getUsername())); // 设置收件人们 final int num = recipients.size(); InternetAddress[] addresses = new InternetAddress[num]; for (int i = 0; i < num; i++) { addresses[i] = new InternetAddress(recipients.get(i)); } message.setRecipients(RecipientType.TO, addresses); // 设置主题 message.setSubject(subject); // 设置邮件内容 message.setContent(content.toString(), "text/html;charset=utf-8"); // 发送 Transport.send(message); } /** * 发送邮件 * * @param recipient * 收件人邮箱地址 * @param mail * 邮件对象 * @throws AddressException * @throws MessagingException */ public void send(String recipient, SimpleMail mail) throws AddressException, MessagingException { send(recipient, mail.getSubject(), mail.getContent()); } /** * 群发邮件 * * @param recipients * 收件人们 * @param mail * 邮件对象 * @throws AddressException * @throws MessagingException */ public void send(List<String> recipients, SimpleMail mail) throws AddressException, MessagingException { send(recipients, mail.getSubject(), mail.getContent()); } }
SimpleMail.java类(缺失部分)
/** * */ package com.study.mail; /** *简单的邮件发送类 * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public class SimpleMail { private String subject;//邮件主题 private String content;//邮件内容 public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
3、调用上面的邮箱发送器,可以构建一个工厂类,工厂类可以封装创建的过程,所以通过读配置文件获取邮箱用户名,密码都会变得十分方便。下面的代码是我在写观察者模式的时候写的,只是简单演示了工厂类。
/** * */ package com.study.mail; /** * * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public class MailSenderFactory { /** * 服务邮箱 */ private static SimpleMailSender serviceSms = null; /** * 获取邮箱 * * @param type 邮箱类型 * @return 符合类型的邮箱 */ public static SimpleMailSender getSender(MailSenderType type) { if (type == MailSenderType.SERVICE) { if (serviceSms == null) { serviceSms = new SimpleMailSender("xx@163.com", "xx"); } return serviceSms; } return null; } }
MailSenderType.java(缺失部分)
/** * */ package com.study.mail; /** *邮箱类型 * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public enum MailSenderType { SERVICE; }
4、发送邮件,还是观察者模式DEMO里面的代码,呼呼。
/** * */ package com.study.mail; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Observer; import javax.mail.MessagingException; import javax.mail.internet.AddressException; /** * * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public class ProductPriceObserver implements Observer { @Override public void update(Observable obj, Object arg) { System.out.println("observer update()"); Product product = null; if (obj instanceof Product) { product = (Product) obj; } if (arg instanceof Float) { Float price = (Float) arg; Float decrease = product.getPrice() - price; if (decrease > 0) { System.out.println("降价了"); // 发送邮件 SimpleMailSender sms = MailSenderFactory .getSender(MailSenderType.SERVICE); List<String> recipients = new ArrayList<String>(); recipients.add("xx@qq.com"); recipients.add("xx@sina.com"); try { for (String recipient : recipients) { sms.send(recipient, "价格变动", "您关注的物品" + product.getName() + "降价了,由" + product.getPrice() + "元降到" + price + "元,降幅达" + decrease + "元人民币。赶快购物吧。"); } } catch (AddressException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } } } }
Product.java(缺失部分)
/** * */ package com.study.mail; import java.util.Observable; /** * * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public class Product extends Observable { private String name; private Float price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Float getPrice() { return price; } public void setPrice(Float price) { synchronized (this) { if(this.price!=null&&this.price!=price){ setChanged(); notifyObservers(price); } this.price = price; } } }
5,最后测试类
/** * */ package com.study.mail; /** * * * @author <a href="ls.zhaoxiangyu@gmail.com">zhao</> * @date 2015-9-22 */ public class Test { public static void main(String[] args) { ProductPriceObserver o=new ProductPriceObserver(); Product p=new Product(); p.setName("apple"); p.setPrice(2.2f); p.addObserver(o); p.setPrice(2.1f); } }
最后附上源码下载地址(免费):http://download.csdn.net/download/osaymissyou0/9131033
补充 javamail Session中Properties属性表:
Session需要使用java.util.Properties来构造,常用的用来构造Session的属性:
属性名 | 含义 |
mail.smtp.user | SMTP的缺省用户名。 |
mail.smtp.host | 要连接的SMTP服务器。 |
mail.smtp.port | 要连接的SMTP服务器的端口号,如果connect没有指明端口号就使用它,缺省值25。 |
mail.smtp.auth | 缺省是false,如果为true,尝试使用AUTH命令认证用户。 |
mail.transport.protocol | 要装入session的协议(smtp、pop3、imap、nntp)。 |
mail.smtp.connectiontimeout | Socket连接超时值,单位毫秒,缺省值不超时。 |
mail.smtp.timeout | Socket I/O超时值,单位毫秒,缺省值不超时。 |
mail.smtp.from | SMTP MAIL使用的Email地址,用来设置邮件的return地址。缺省是Message.getFrom()或InternetAddress.getLocalAddress()。注意:mail.smtp.user优先使用 |
mail.smtp.localhost | localhost名,缺省是 InetAddress.getLocalHost().getHostName()。如果JDK和name service正确配置,一般不需设置。 |
mail.host | 邮件交互的主机。 |
mail.smtp.ehlo | 如果为false,那么不会尝试使用EHLO命令登录,缺省是true。通常EHLO命令失败,会倒退到HELO命令。这个属性只有在服务器没有fail EHLO属性或没有实现EHLO属性。 |
mail.user | 登录邮件服务器的用户名(发送邮件时需要)。 |
mail.from | 发件人地址(发送邮件时需要)。 |
相关文章推荐
- 使用 Java 实现 Comet 风格的 Web 应用
- 转:Eclipse Debug 界面应用详解——Eclipse Debug不为人知的秘密
- 感谢曾经不放弃的自己
- Java parseInt()和parseFloat()的用法
- Java学习之Iterator(迭代器)的一般用法
- Java很容易出错的一些问题
- java多线程关键字synchronized用法
- JAVA正则表达式:Pattern类与Matcher类详解(转)
- java list三种遍历方法性能比较
- Java中的异常处理中的需要知道的异常类
- 细数JDK里的设计模式
- Solr IV——Solr查询
- struts2的空指针异常札记
- 用java scripting 动态脚本配合java使用
- 怎么样eclipse发达国家多重聚合关系maven项目和使用git管理
- Java集合---ConcurrentHashMap原理分析
- 大龄屌丝自学笔记--Java零基础到菜鸟--021
- java动态代理(JDK和cglib)
- Java加密算法笔记
- Java集合---HashMap源码剖析