这期内容当中小编将会给大家带来有关如何进行JavaMail开发,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都食品包装袋小微创业公司专业提供企业网站建设营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。
引入:最近项目中要做一个简单的邮件功能,即从前台输入邮件内容,去配置文件中读取发件人、收件人等信息后,然后发送邮件到指定的邮箱,其中收件人和抄送人可以有多个,基于这个需求,查询了相关资料,决定采用JavaMail这个插件来实现。
preparation:
1.JavaMail的介绍
JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。
虽然JavaMail是Sun的API之一,但它目前还没有被加在标准的java开发工具包中(JavaDevelopmentKit),这就意味着你在使用前必须另外下载JavaMail文件。除此以外,你还需要有Sun的JavaBeans Activation Framework (JAF)。JavaBeans Activation Framework的运行很复杂,在这里简单的说就是JavaMail的运行必须得依赖于它的支持。在Windows 2000下使用需要指定这些文件的路径,在其它的操作系统上也类似。
JavaMail是可选包,因此如果需要使用的话你需要首先从java.sun.com下载。目前最新版本是JavaMail1.4,使用JavaMail的时候需要Javabean Activation Framework的支持,因此你也需要下载JAF。安装JavaMail只是需要把他们加入到CLASSPATH中去,如果你不想修改 CLASSPATH的话,可以直接把他们的jar包直接copy到JAVA_HOME/lib/ext下。这样JavaMail就安装好了。
JavaMail包中用于处理电子邮件的核心类是:Session,Message,Address,Authenticator,Transport,Store,Folder等。Session定义了一个基本的邮件会话,它需要从Properties中读取类似于邮件服务器,用户名和密码等信息
2.下载jar包
网上有下载链接,但是这里我还是把jar包给上传
javamail-1[1].4.2.zip
jaf-1_1_1.zip
dom4j.jar 这个jar就不提供下载资源了
3.项目环境
system:win7 myeclipse:6.5 tomcat:5.0 JDK:编译和运行都是1.4
为了方便,还是在之前的UpDown项目下运行的,本次用到的文件只有sendmail包下的文件。
4.class&method
请参考:http://www.jspcn.net/htmlnews/1150019680500144.html
start
导入javamail、JAF、dom4j的jar包,然后新建对应的文件如下:
Encrypt.jar 主要是用于对密码进行加密和解密
package sendmail; /** * Module: Encrypt.java * Description: 对密码进行加密和解密 * Company: * Author: ptp * Date: Mar 6, 2012 */ public class Encrypt { public static final int pass1 = 10; public static final int pass2 = 1; public Encrypt() { } /** * @Title: DoEncrypt * @Description: 对密码进行加密的方法 * @param @param str * @param @return 设定文件 * @return String 返回类型 * @throws */ public static String DoEncrypt(String str) { StringBuffer enStrBuff = new StringBuffer(); for (int i = 0; i < str.length(); i++) { int tmpch = str.charAt(i); tmpch ^= 1; tmpch ^= 0xa; enStrBuff.append(Integer.toHexString(tmpch)); } return enStrBuff.toString().toUpperCase(); } /** * @Title: DoDecrypt * @Description: 对密码进行解密的方法 * @param @param str * @param @return 设定文件 * @return String 返回类型 * @throws */ public static String DoDecrypt(String str) { String deStr = str.toLowerCase(); StringBuffer deStrBuff = new StringBuffer(); for (int i = 0; i < deStr.length(); i += 2) { String subStr = deStr.substring(i, i + 2); int tmpch = Integer.parseInt(subStr, 16); tmpch ^= 1; tmpch ^= 0xa; deStrBuff.append((char)tmpch); } return deStrBuff.toString(); } public static void main(String args[]) { String source = "123456"; String s = DoEncrypt(source); System.out.println("de=" + s); source = DoDecrypt(s); System.out.println("en=" + source); } }
MailInfo.java javabean定义邮件需要的字段以及对应的get和set方法
package sendmail; /** *Module: MailInfo.java *Description: 定义发送邮件的所有字段的javabean *Company: *Author: ptp *Date: Mar 1, 2012 */ public class MailInfo{ private String host;// 邮件服务器域名或IP private String from;// 发件人 private String to;// 收件人 private String cc;// 抄送人 private String username;// 发件人用户名 private String password;// 发件人密码 private String title;// 邮件的主题 private String content;// 邮件的内容 public String getHost() { return host; } public void setHost(String host) { this.host = host; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getCc() { return cc; } public void setCc(String cc) { this.cc = cc; } 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 getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
MyAuthenticator.java 用于对邮件授权
package sendmail; /** *Module: MailInfo.java *Description: 邮件授权类 *Company: *Author: ptp *Date: Mar 6, 2012 */ import javax.mail.PasswordAuthentication; public class MyAuthenticator extends javax.mail.Authenticator { private String strUser; private String strPwd; public MyAuthenticator(String user, String password) { this.strUser = user; this.strPwd = password; } protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(strUser, strPwd); } }
SendMail.java 发送邮件的封装类
先读取xml配置文件,然后解析xml文件,最后取得配置文件的值封装完成后发邮件
package sendmail; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.Properties; import javax.mail.Message; 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; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; /** * Module: SendMail.java * Description: 发送邮件 * Company: * Author: ptp * Date: Mar 1, 2012 */ public class SendMail { private static final Log log = LogFactory.getLog(SendMail.class); // 配置文件xml的路径 private final static String XML_PATH = "src" + File.separator + "sendmail" + File.separator + "SendMail.xml"; //xml文件中字段对应的javabean对象 private static MailInfo mailInfo = new MailInfo(); /** *Title: readXML
*Description:读取xml文件,把文件内容以字符串形式输出
* @param xmlPath 配置文件的路径 * @return * @throws Exception */ private String readXML(String xmlPath) throws Exception { log.debug("xmlPath="+xmlPath); String fileContent = ""; File file = new File(xmlPath); if (file.isFile() && file.exists()) { try { InputStreamReader read = new InputStreamReader( new FileInputStream(file), "UTF-8"); BufferedReader reader = new BufferedReader(read); String line; try { while ((line = reader.readLine()) != null) { fileContent += line; } reader.close(); read.close(); } catch (IOException e) { e.printStackTrace(); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } }else{ throw new Exception("config目录下的配置文件SendMail.xml不存在,请检查"); } log.debug("xml="+fileContent); return fileContent; } /** *Title: parseXML
*Description:发送邮件给指定的收件人和抄送人,同时进行一些简单的校验判断,如必填项的字段、type的值
* @param xml 配置文件的内容 * @param type 邮件类型 */ private void parseXML(String xml, String type) { type=type.toLowerCase();//忽略type字段的大小写 try { // 解析XML,获得doc对象 Document doc = DocumentHelper.parseText(xml); // 判断type的值是否正确,type的值应是报文二级节点中的一个 String flag = doc.getRootElement().element(type) + ""; if (null == flag || flag.equals("null")) throw new DocumentException( "传入的type值不对,type的值应是SendMail.xml报文中二级节点的一个,请查看文件然后重新传入type的值"); // 设置主机名称 Element hostEle = (Element) doc.selectSingleNode("/mail/" + type + "/host"); if (null == hostEle || "".equals(hostEle.getTextTrim())) { throw new DocumentException("邮件服务器域名或IP不能为空,请检查配置文件SendMail.xml"); } mailInfo.setHost(hostEle == null ? "" : hostEle.getTextTrim()); // 设置发件人 Element fromEle = (Element) doc.selectSingleNode("/mail/" + type + "/from"); if (null == fromEle || "".equals(fromEle.getTextTrim())) { throw new DocumentException("发件人地址不能为空,请检查配置文件SendMail.xml"); } mailInfo.setFrom(fromEle == null ? "" : fromEle.getTextTrim()); // 设置邮件主题 Element titleEle = (Element) doc.selectSingleNode("/mail/" + type + "/title"); mailInfo.setTitle(titleEle == null ? "" : titleEle.getTextTrim()); // 设置收件人,对多个收件人的处理放在后面 Element toEle = (Element) doc.selectSingleNode("/mail/" + type + "/to"); if (null == toEle || "".equals(toEle.getTextTrim())) { throw new DocumentException("收件人地址不能为空,请检查配置文件SendMail.xml"); } mailInfo.setTo(toEle == null ? "" : toEle.getTextTrim()); // 设置抄送,对多个抄送人的处理放在后面 Element ccEle = (Element) doc.selectSingleNode("/mail/" + type + "/cc"); mailInfo.setCc(ccEle == null ? "" : ccEle.getTextTrim()); //设置发件人用户名 Element nameEle = (Element) doc.selectSingleNode("/mail/" + type + "/username"); if(null==nameEle||"".equals(nameEle.getTextTrim())){ throw new DocumentException("发件人用户名不能为空,请检查配置文件SendMail.xml"); } mailInfo.setUsername(nameEle == null ? "" : nameEle.getTextTrim()); //设置发件人密码 Element passEle = (Element) doc.selectSingleNode("/mail/" + type + "/password"); if(null==passEle||"".equals(passEle.getTextTrim())){ throw new DocumentException("发件人密码不能为空,请检查配置文件SendMail.xml"); } mailInfo.setPassword(passEle == null ? "" : passEle.getTextTrim()); } catch (DocumentException e) { e.printStackTrace(); } } /** *Title: sendMailOfValidate
*Description:发送邮件的方法,Authenticator类验证
*/ private void sendMailOfValidate() { Properties props = System.getProperties(); props.put("mail.smtp.host", mailInfo.getHost());//设置邮件服务器的域名或IP props.put("mail.smtp.auth", "true");//授权邮件,mail.smtp.auth必须设置为true String password=mailInfo.getPassword();//密码 try { password=Encrypt.DoDecrypt(password);//如果密码经过加密用此方法对密码进行解密 } catch (NumberFormatException e1) { //如果密码未经过加密,则对密码不做任何处理 } //传入发件人的用户名和密码,构造MyAuthenticator对象 MyAuthenticator myauth = new MyAuthenticator(mailInfo.getUsername(),password); //传入props、myauth对象,构造邮件授权的session对象 Session session = Session.getDefaultInstance(props, myauth); //将Session对象作为MimeMessage构造方法的参数传入构造message对象 MimeMessage message = new MimeMessage(session); try { message.setFrom(new InternetAddress(mailInfo.getFrom()));//发件人 // 对多个收件人的情况进行处理,配置文件SendMail.xml中每个收件人之间必须用逗号隔开的 if (mailInfo.getTo() != null && !"".equals(mailInfo.getTo())) { String to[] = mailInfo.getTo().split(","); for (int i = 0; i < to.length; i++) { message.addRecipient(Message.RecipientType.TO, new InternetAddress(to[i]));// 收件人 } } // 对多个抄送人的情况进行处理,每个抄送人之间用逗号隔开的 if (mailInfo.getCc() != null && !"".equals(mailInfo.getCc())) { String cc[] = mailInfo.getCc().split(","); for (int j = 0; j < cc.length; j++) { message.addRecipient(Message.RecipientType.CC, new InternetAddress(cc[j]));// 抄送 } } message.setSubject(mailInfo.getTitle());// 主题 message.setText(mailInfo.getContent());// 内容 Transport.send(message);// 调用发送邮件的方法 log.debug("邮件发送成功"); } catch (AddressException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } /** *Title: sendMail
*Description:外部程序调用的入口
* @param type 邮件的类型,目前有三种,即logmessage、checkmessage、ordermessage,type只能传这三个值中一个,传其他的任何值都不行 * @param content 邮件的内容 * @throws Exception */ public void sendMail(String type,String content) throws Exception{ log.debug("入参type="+type); log.debug("入参content="+content); if (null == type || "".equals(type) || null == content || "".equals(content)) { throw new Exception("方法的入参type和content字段的值都不能为空或null"); } String xml=readXML(XML_PATH);//获得xml字符串 parseXML(xml,type);//解析xml字符串,把对应字段的值放入到mailInfo对象中 mailInfo.setContent(content);//设置发送的内容 sendMailOfValidate();//发送邮件 } /** * 为了方便直接用main方法测试 * @param args * @throws Exception */ public static void main(String args[]) throws Exception { SendMail mail = new SendMail(); // type类型,根据此字段去配置文件SendMail.xml中匹配,然后发到相应的邮箱 String type = "logmessage"; // 邮件的内容,实际开发中这个内容是前台传到后台 String content = "你好,欢饮使用JavaMail包开发邮件功能"; // 在其他类中调用时只能看到sendMail方法,为了保护内部细节,其它的方法都声明为私有的 mail.sendMail(type, content); //这个项目中没有日志文件,所以我打印一句话来告诉自己程序已经成功运行 System.out.println("****success****"); } }
说明:代码中的校验可能不太严谨和全面,因为这个配置文件是由开发人员自己配置,并且对配置文件也有详细的介绍,所以代码中就省略去了许多的校验。
SendMail.xml 邮件配置文件
smtp.qq.com 838045782@qq.com 838045782@qq.com,taipeng0820@163.com 838045782@qq.com test JavaMail 838045782@qq.com 123456
注意:密码是必填项,由于是介绍,我把自己的密码给删掉换成了123456,实际中需根据需要配置邮件服务器域名、发件人、收件人、抄送人、用户名和密码。
result
运行方式:执行运行SendMail.java类中的main方式就可以测试了,测试之前请按说明配置xml文件。
首次运行你可能会遇到以下的错误,所以note.txt文件就用来提供遇到的错误以及对应的解决方案
note.txt
java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream at javax.mail.Session.loadProvidersFromStream(Session.java:928) at javax.mail.Session.access$000(Session.java:174) at javax.mail.Session$1.load(Session.java:870) at javax.mail.Session.loadResource(Session.java:1084) at javax.mail.Session.loadProviders(Session.java:889) at javax.mail.Session.(Session.java:210) at javax.mail.Session.getDefaultInstance(Session.java:299) at mail.SendMail.sendMail(SendMail.java:31) at mail.SendMail.main(SendMail.java:50) Exception in thread "main"
解决方案:在myeclipse的安装目录下搜索javaee.jar,然后用压缩软件打开,删除javax下的mail文件夹
java.lang.NoClassDefFoundError: com/sun/activation/registries/LogSupport at javax.activation.MailcapCommandMap.(MailcapCommandMap.java:140) at javax.activation.CommandMap.getDefaultCommandMap(CommandMap.java:61) at javax.activation.DataHandler.getCommandMap(DataHandler.java:153) at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:611) at javax.activation.DataHandler.writeTo(DataHandler.java:315) at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:264) at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1299) at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2071) at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2039) at javax.mail.Transport.send(Transport.java:119) at mail.SendMail.sendMailNoValidate(SendMail.java:48) at mail.SendMail.main(SendMail.java:96) Exception in thread "main"
解决方案:在myeclipse的安装目录下搜索javaee.jar,然后用压缩软件打开,删除javax文件夹下的activation文件夹
javax.mail.SendFailedException: Sending failed; nested exception is: javax.mail.MessagingException: 503 Error: need EHLO and AUTH first ! at javax.mail.Transport.send0(Transport.java:219) at javax.mail.Transport.send(Transport.java:81) at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMailNoValidate(SendMailServiceImpl.java:210) at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMail(SendMailServiceImpl.java:243) at com.asiainfo.bboss.sendmail.SendMailServiceImpl.main(SendMailServiceImpl.java:261)
解决方案:props.put("mail.smtp.auth", "true");
javax.mail.SendFailedException: Sending failed; nested exception is: javax.mail.AuthenticationFailedException at javax.mail.Transport.send0(Transport.java:219) at javax.mail.Transport.send(Transport.java:81) at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMailNoValidate(SendMailServiceImpl.java:211) at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMail(SendMailServiceImpl.java:244) at com.asiainfo.bboss.sendmail.SendMailServiceImpl.main(SendMailServiceImpl.java:262)
解决方案: MyAuthenticator myauth = new MyAuthenticator(mailInfo.getUsername(),password);
运行截图如下:
图1:myeclipse后台打印的结果 此项目下没有log4j.properties文件,故会有红色的信息,代码中的log也没有打印出来
图2:去我的QQ邮箱收信---收件箱列表
图3:去我的QQ邮箱收信---邮件内容
图4:去我的163邮箱收信---收件箱列表
确认已经收到邮件,因为163邮件显示的是本人的真实姓名,这里就不截图了。
图5:去我的163邮箱收信---邮件内容
确认已经收到邮件,因为163邮件显示的是本人的真实姓名,这里就不截图了。
以上只是对javamail插件一个小小的应用,此插件也可以做收信、转发、答复、上传附件等功能,
上述就是小编为大家分享的如何进行JavaMail开发了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。