怎样有自信才能有定力定时发信,我想要一个邮件在一个月以后发出去

小木虫 --- 700万学术达人喜爱的学术科研平台
热门搜索:
&&论文投出去1个月
还是Editor Invited
怎么办???
可以发邮件催一下不
论文投出去1个月
还是Editor Invited
怎么办???
可以发邮件催一下不
大神们指点下嘛& && && & 最好给个给编辑写信的模板嘛
学术必备与600万学术达人在线互动!
扫描下载送金币
北京学而思教育科技有限公司 地址:北京市海淀区北三环甲18号中鼎大厦A座1层102室 电话:010-当前位置: >>
如何用javamail定时发送邮件
如何用 javamail 定时发送邮件 例如:我想在 3 天后的中午 12:00 发送给别人邮件 还有就是每天的中午 12 点给别人发送邮件,而且这些个邮件地址是从一个 jsp 传来的 例如今天给
发,当执行过 jsp 后,jsp 输入的是 ,以后就给
发 而且 jsp 传过来的邮件地址数目是多个的,每天需要给多人在固定一时间内发邮件 定时触发器 有许多开源项目 Timer + 多线程 White 构建的一个简单通用的计划框架,以用我在这里使用的 Java 计时器框架是由 Java 开发人员 Tom 过多的介绍,详细信息在 IBM于执行任意复杂的计划任务,他使我们实现灵活的计划策略成为可能.Java 计时器框架的本身在这里不作 developerWorks 中国网站.我们主要讨论如何利用 Java 计时器框架在 Solaris 平台来实现邮件的定时发送, JavaMail 发送邮件的实现 以及在 Solaris 平台上如何以后台方式运行整个邮件定时发送的应用. 下载本文的源代码,参考具体实现. 形成 schedule.jar 包1.1schedule.jar 包中的目录结构如下:我们将数据库的连接,日志,邮件和计划框架的通用类形成一个与具体应用要求无关的 schedule.jar 包. 利 用 javac 将 编 译 生 成 的 目 标 class 文 件 存 在 当 前 目 录 的 classes 文 件 夹 下 , 然 后 通 过 jar -cvf schedule.jar ./*命令生成 schedule.jar 包.1.1.1Oracle 数据库连接的建立位于 db 目录下,通过 thin 方式建立与 Oracle 的数据库连接,具体的实现参见《J2EE 应用中与 Oracle 数 据库的连接》一文. 日志1.1.2以后台方式定时运行的应用应特别注意日志的功能,因为只有通过分析详细的日志信息才能准确掌握应 用的执行情况.在 logs 目录下为 Logs.java 文件,代码如下: package import import import com.j2ee. java.io.*; java.util.*; java.text.SimpleDateF public { private private private privateclass String String String newLogs logType=&&; server=&/schedule/logs/server.log&; task=&/schedule/implements/nohup.out&; dateFormat = E a HH:mm:ss 】&); yyyy 年 MM 月 dd 日SimpleDateFormatSimpleDateFormat(&【/** * */ public { this.logType=logT } public { try { String if if // BufferedWriter = String if (logType.equals(&task&)) new str=dateFormat.format(new out BufferedWriter(new Date()); FileWriter(path,true)); path=&&; (logType.equals(&server&)) (logType.equals(&task&)) void print(String msg) Logs(String logType) @param logType server taskpath= path=out.newLine(); out.write(str,0,str.length()); out.write(msg,0,msg.length()); out.newLine(); out.close(); } catch(Exception { System.out.println(&Logs.print:&+e.getMessage()); } } }; e) 通过类中的构造器,可以生成两个日志文件:server.log 和 nohup.out.server.log 用来记录计时器框架本 身定时调度的日志信息,通过它来判断定时调度服务每天是否正常运行;nohup.out 用来记录在具体应用 中的调试信息,例如:在应用中通过 System.out.println()输出的信息将记录在 nohup.out 文件中. 1.1.3 邮件位于 mail 目录下,包括以下一些文件: 1)Debug.java 发送邮件时的调试信息 邮件的正文,为了使邮件接受者对收到的邮件有一个好的视觉效果,可以先写2)EMailContents.java一个统一的 HTML 邮件模板,在模板中填充相应的内容.EmailContents 类完成这一功能.效果如下:3)Mailer.java发送邮件的主方法.它调用 MailThread 类中的方法创建一个发送邮件的线程. 发送邮件线程类.它调用 MailHelper 中的方法来完成发送邮件的工作. 发送邮件的实现类.在类的 createAndSendMail 方法中包括了发送邮件一系列必须4)MailThread.java 5)MailHelper.java 和 activation.jar. 1.1.4 计划框架的过程, 它可以完成一些邮件的正文, 附件, 抄送, 回执等功能. 在邮件的实现中用到了两个 jar 包: mail.jar计划框架的详细内容可以通过本文前面提供的连接去详细了解,本文该部分的代码也出自 IBM 网站. 1.2 邮件定时发送的实现这部分主要用到前面 schedule.jar 中的类来实现与具体应用要求相适应的应用.在 implements 目录下有 三个类: 包含一个 main 方法,在本例中&每天计划 3 点开始执行计划好的任务&. 线程类,在该类的 run 方法中,可以添加不同类型的计划定时执行的任务类1)ScheduleTask.java 2)ScheduleThread.java来完成不同的定时执行的任务,在本例中调用了 Mails 类中的 sendMail 方法来定时发送邮件. 3)Mails.java 1.3 按照一定的业务逻辑规则实现邮件的发送.邮件定时发送应用的运行包括应用的启动和停止,在 Solaris 上我们可以编写两个脚本:start 和 stop 来完成该工作. 1.3.1 Start 脚本 Start 脚本内容如下: echo '************************************************************'CLASSPATH=.:/schedule/implements/jar/schedule.jar: /schedule/implements/jar/classes12.zip: /schedule/implements/jar/mail.jar:/schedule/implements/jar/activation.jar export echo nohup echo echo echo echo date echo echo CLASSPATH 'set java 'start 'view ' ' && schedule schedule logs:' /schedule/implements/nohup.out' /schedule/logs/server.log' /schedule/logs/server.log && /schedule/logs/server.log running task environment success.' success.' & com.j2ee.implement.ScheduleTask'计划框架成功启动''************************************************************'这里有两个关键点:CLASSPATH 的设置和 nohup 运行方式.在 CLASSPATH 中必须提供用到的所有 jar 包,多个 jar 包用&:&分隔;&&&表示以后台方式运行,&nohup&使应用的运行不依赖于当前的会话,如果不 以&nohup&方式的话,即& java com.j2ee.implement.ScheduleTask -ef | grep &&,当你关闭你当前的会话时, 应用将终止运行.可以使用&ps java&来查看应用运行的进程号.当然也可以通过手工交互的方式完成上述步骤来运行应用. Stop 脚本1.3.2Stop 脚本内容如下: echo ps kill rm date echo echo echo -e -9 && 'stop '************************************************************' | grep -c java 2-6 && ps.out `cut ps.out`ps.out /schedule/logs/server.log && task /schedule/logs/server.log success.' schedule '计划框架成功停止''************************************************************' ps -e | grep java&命令将输出信息重定向到&ps.out&文件中,在从文件中该脚本中主要通过&获得进程号,然后将它 kill 掉.同样也可以通过手工的方式将它 kill. 一般的问题在 SUN 中国的技术社区都能找的到的 这篇是切过来的 建议你去看看.你可以去 SUN 中国技术社区下载具体实例 使用 JSP 开发 WebMail 系统电子邮件(E-mail)是 Internet 上使用最广泛的服务之一,传统的 Email 应用模式基于 C/S 结构,即用 户使用客户端的邮件收发工具 (如 Outlook, Foxmail 等) 与提供邮件服务的服务器 (如 163.net, 263.net, 371.net)通信,在使用客户端邮件工具之前,用户要进行一些必要的设置,如指定邮件服务器的主机地 址和通信端口等,这些工作对刚开始上网的用户会有一定的困难,如果把 E-mail 和 Web 结合在一起,即 通过 Web 编程和适当的系统设置,使用户仅仅以访问 Web 的方式就可以得到和使用完整的邮件服务,这 样将极大地方便上网用户,这种系统称为 WebMail.WebMail 是目前 Internet 上最受欢迎的服务之一, 也是很多网站必备功能之一.另外 WebMail 同样也适用于企业或校园网的应用.通常在后台服务器的搭建和设置完成后实现 WebMail 系统,而前台的开发工作主要是开发工具与后 台数据库和邮件服务器的交互问题.在 Linux 平台上运行的各种服务器软件稳定性和可靠性一直很好,而 且选择跨平台的 Java 开发工具使系统更稳定,具有更高的伸缩性.JSP 性能尽管 JSP 提供强大的功能是建立在 Servlet 之上, JSP 的性能和 Servlet 相差无几. 但 JSP 首先要编 译成 Servlet,这只会增加少量的代码,仅需编译一次且可以预编译,这就消除了运行时花费不必要的负 担.JSP 与 Servlet 性能上的差异仅仅表现在返回的数据是二进制的.这是因为 JSP 返回时用的是 PrintWriter,而 Servlet 可以应用于速度更快的 OutputStream.JSP 自定义的标签库可以封装大量的,复杂的 Java 操作在一个 Form 里面,这些预先定义好的标签 可以很容易的被那些没有 Java 知识的人调用.因此,JSP 自定义的标签库可以有效地实现 Java 程序员和 Web 设计人员工作的划分.然而,在页面上应用的每一个标签,Web 容器都必须创建一个新的标签句柄 对象或从标签缓冲中提取它.因此,过多的应用自定义的标签将会带来不必要的资源浪费.BodyTags 是一种特殊的定制标签,可以提取在它之间封装的内容或者替换那些内容.BodyTags 之 间的内容一般会备份在内存中.由于 BodyTags 之间能够嵌套和重复,因此,在程序中应用了多级的 BodyTags 会占用大量宝贵的内存和系统资源. 实现 WebMail 的主要功能该系统提供了获取,阅读,书写,转发,回复,打印,删除及用户管理的功能.考虑到系统的跨平台 性,采用 Java 及相关技术产品为开发工具,特别是采用 JSP 作为服务程序,这样对客户端也没有其它要 求,同时系统的性能在高负荷下得到进一步提高.整个 WebMail 系统全部采用纯 Java 代码,服务器端每 响应一个服务请求启动一个线程, 而不像 CGI 那样启动一个进程. 这样能够节省系统资源, 提高系统性能.实现主要代码获取用户输入的信息 获取用户输入的信息对于用户输入内容获取功能是通过 getParameter 方法来实现的,对于输入的文本内容,通过如下代 码就能在服务器端获取,程序代码如下:String username=request.getParameter(&login&);String password=request.getParameter(&password&);Session session2=Session.getInstance(System.getProperties() ,null);Store store=session2.getStore(&pop3&);根据用户输入的信息来连接服务器,程序代码如下:try{ store.connect(host,username &%nyist.net&, password);}catch(javax.mail.AuthenticationFailedException e){content=&用户名与密码不匹配&;}接收邮件代码段根据获取用户输入的信息来连接服务器,代码为:store.connect(&nyist.net&,-1,request.getParameter(&username&) &%nyist.net&,request.getParameter(&password&));获取服务器端的信息,代码如下:Folder folder = store.getFolder(&INBOX&);Folder.open (Folder.READ_WRITE);Message message[]=folder.getMessages(); FetchProfile fp=new FetchProfile();fp.add(FetchProfile.Item.ENVELOPE);fp.add(FetchProfile.Item.FLAGS);fp.add(&X-Mailer&);folder.fetch(message,fp);根据服务器上信息的不同格式,使用不同的方式来读取:String contentbody=&&;Object o=message[j].getContent();若其 Type 为 tex/plain 就可直接读出,代码如下:if (message[j].isMimeType(&text/plain&)) { contentbody=(String) &&/td&&; StringBuffer buf=new StringBuffer(contentbody.length() 6); char ch=' '; for(intp=0;p&contentbody.length();p )// 若 遇 到 换 行 就 转 为 &br& {ch=contentbody.charAt(p); if(ch=='\n')buf.append(&&br&&); else buf.append(ch); } contentbody=buf.toString(); }如果信息类型为 text/html,不同的信息类型处理的方式稍有不同(如下段代码) ,由于篇幅有限不再 一一说明.else if (message[j].isMimeType(&text/html&))contentbody=(String)o &&/td&&;发送邮件代码段根据用户输入的内容,获取邮件头信息代码如下:String host = &nyist.net&;String from = request.getParameter(&from&);String to = request.getParameter(&to&);String subject = request.getParameter(&subject&);String content = request.getParameter(&content&);Properties props = System.getProperties(); //设置邮件服务props.put(&mail.smtp.host&, host);Session session2 =Session.getInstance(props, null);设置邮件头信息代码如下:MimeMessage message =new MimeMessage(session2);message.setFrom(new InternetAddress(from));message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));message.setSubject(subject);message.setSentDate(new Date());// create the message partMimeBodyPart messageBodyPart =new MimeBodyPart();设置邮件内容,构建程序段如下:messageBodyPart.setText(content); Multipart multipart = new MimeMultipart();multipart.addBodyPart(messageBodyPart);用户在发送邮件时常常带有附件,就是将浏览器客户端用户本地的文件传送到 POP 客户端,实现代码 如下:for (int i=0;i&mySmartUpload.getFiles().getCount();i ){com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(i);if (!myFile.isMissing()) {myFile.saveAs(&/upload/&myFile.getFileName());count;}在上传附件的同时,对上传文件的数量进行统计,并通过 out.println(&上传了& count &个文件&)将 其在屏幕上显示出来.在发送的信件中如果有附件,使用如下代码进行发送: for(int i=0;request.getParameter(&file& i)!=i ){messageBodyPart = new MimeBodyPart();File file=new File(&/home/mengyu/ROOT/upload/&,request.getParameter(&file& i));DataSource source =new FileDataSource(file);messageBodyPart.setDataHandler(new DataHandler(source));messageBodyPart.setFileName(request.getParameter(&file& i));multipart.addBodyPart(messageBodyPart);}// Put parts in messagemessage.setContent(multipart);调用 Transport 的 send 方法,将构造好 MIME Message 对象发送出去,代码如下: Transport.send(message);删除电子邮件代码段在通过 Web 界面使用电子邮件过程中,经常要对接收到垃圾邮件或已查看过的邮件进行删除,这也 是电子邮件中必不可少的一个功能,所以我们设计了 Web 界面中删除电子邮件的相应功能,主要程序代 码段如下:Folder folder=store.getFolder(&INBOX&);folder.open(Folder.READ_WRITE);Message message[]=folder.getMessages();String msg[]=request.getParameterValues(&msg&);for(int i=0,n=msg.i&n;i )message[Double.valueOf(msg[i]).intValue()].setFlag(Flags.Flag.DELETED,true);folder.close(true); 用户管理在使用系统运行的过程中,通过管理界面添加用户,删除不必要的用户,修改用户的密码,这是程序 运行过程中必要的模块,代码如下: //添加用户Runtime.getRuntime().exec(&/home/vpopmail/bin/vadduser& request.getParameter(&username&) &@nyist.net & request.getParameter(&passwd&));//删除用户Runtime.getRuntime().exec(&/home/vpopmail/bin/vdeluser& request.getParameter(&username&) &@nyist.net&);//修改用户密码Runtime.getRuntime().exec(&/home/vpopmail/bin/vpasswd& request.getParameter(&username&) &@nyist.net & request.getParameter(&passwd&));总结 Java 简化了企业解决方案的开发,部署和管理等相关的复杂问题,它是面向对象的编程语言,同时也 是具有平台独立性,高性能的服务器端编程语言.它提供的标准系统框架和服务适合团体开发,可控制性 好,与其它资源的集成性好.采用 Java 为编程工具开发高性能,高可用性的 WebMail 服务器具有非常重 要的意义.javamail 邮件服务发送总结首先我们得得到属性文件! Properties props = new Properties(); 然后将你要 SMTP 的服务器添加带此:bean.getServer() props.put(&mail.smtp.host&, bean.getServer()); props.put(&mail.transport.protocol&, &smtp&);//props.put(&mail.smtp.connectiontimeout&, &10000&);这个注释是延时 // props.put(&mail.smtp.timeout&, &10000&);props.put(&mail.smtp.auth&, &true&);如果你的 smtp 有验证则需要把后面写为 true!一般 163 soh u 等都需要验证! MyAuthenticator auth = new MyAuthenticator(bean.getUser(), bean.getPassword()); 一个验证类在下面会贴出来sendMailSession = Session.getDefaultInstance(props, (Authenticator) auth); 然后我们得到 session 将配置文件与验证类写进去 sendMailSession.setDebug(true);//需要调试可以打 MimeMessage msg = new MimeMessage(sendMailSession); InternetAddress fromAddress = new InternetAddress(bean.getFrom()); msg.setFrom(fromAddress); 发送人地址 // msg.setRecipient(Message.RecipientType.TO, new InternetAddress(bean.getTo())); 收件人地址 if(bean.getToEmail()!=null){ for(int i=0;i&bean.getToEmail().i++){ msg.addRecipients(Message.RecipientType.TO, bean.getToEmail()[i]); } 多个可以这样写(同收件人地址) } // Get two Object mp = new MimeMultipart(); BodyPart bp = new MimeBodyPart(); // Set Subject msg.setSubject(bean.getSubject(), &UTF-8&); 标题 // Set Context bean.setContext(new String(bean.getContext().getBytes(&UTF-8&),&UTF-8 &)); bp.setContent(&&meta http-equiv=Content-Type content=text/ charse t=gb2312&&+bean.getContext(),&text/charset=utf-8&); 内容 mp.addBodyPart(bp); 将 标题与内容添加 //Set Ps if(bean.getFile()!=&&){ 如果有附件则运行下面代码 bp = 先清空他bp = new MimeBodyPart(); FileDataSource fileds = new FileDataSource(bean.getFile()); bp.setDataHandler(new DataHandler(fileds)); bp.setFileName(fileds.getName()); 将文件 set 进去 mp.addBodyPart(bp); 添加文件 } msg.setSentDate(new java.util.Date()); set 时间 msg.setContent(mp); 将所有信息内容 set msg.saveChanges();保存 transport = sendMailSession.getTransport(&smtp&); System.out.println(&Sending Mail....&); transport.connect(bean.getServer(), bean.getUser(), bean.getPassword()); transport.sendMessage(msg, msg.getAllRecipients()); 发送所有 transport.close(); System.out.println(&OK.&);呵呵.最近研究邮件发送系统.总算搞出来了. ~现在总结总结.其实也不算总结.给点注释就 OK 了 呵呵. . 看上面注释下面是验证内: package org.softeem.import javax.mail.A import javax.mail.PasswordApublic class MyAuthenticator extends Authenticator { private S private Spublic MyAuthenticator(String un, String up) { super(); username = userpass = }public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, userpass); } }今天在研究 javamail 发信的过程中,出现了一些小问题,现总结如下,以免后来者走些不 必要的弯路,先把完整的能够正常运行的代码示例粘贴如下: 发邮件源代码: package com.hyq.import java.util.P import javax.mail.*; import javax.mail.internet.*;public class MailExample { public static void main (String args[]) throws Exception {String host = &&; String from = &你自己的电子信箱&; String to = &收件人信箱&;//发件人使用发邮件的电子信箱服务器 //发邮件的出发地(发件人的信箱)//发邮件的目的地(收件人信箱)// Get system properties Properties props = System.getProperties();// Setup mail server props.put(&mail.smtp.host&, host);// Get session props.put(&mail.smtp.auth&, &true&); //这样才能通过验证MyAuthenticator myauth = new MyAuthenticator(&你自己的电子信箱&, &你自 己的信箱密码&); Session session = Session.getDefaultInstance(props, myauth);//session.setDebug(true);// Define message MimeMessage message = new MimeMessage(session);// Set the from address message.setFrom(new InternetAddress(from));// Set the to address message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));// Set the subject message.setSubject(&测试程序!&);// Set the content message.setText(&这是用 java 写的发送电子邮件的测试程序!&);message.saveChanges();Transport.send(message);} }校验发信人权限的方法 package com.hyq.import javax.mail.PasswordAclass MyAuthenticator extends javax.mail.Authenticator { private String strU private String strP public MyAuthenticator(String user, String password) { this.strUser = this.strPwd = }protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(strUser, strPwd); } }注意:上面的事例仅为使用 163 信箱时发送电子邮件的方法,因为使用的 host 为:smtp. ,如源代码中:String host = &&; //发件人使用发邮件的电子信箱服务器, 如果使用其它的电子邮件发送, 就必须在其邮件服务器上查找相应的电子邮 件服务器,例如搜狐就要使用 ,具体情况具体对待,都可以从所使用的邮 件服务器上获得的.如果没有使用 host ,也就是说,没有进行 props.put(&mail.smtp. host&, host);设置, 那么就会抛 javax.mail.MessagingException: Could not conne ct to SMTP host: localhost, port: 25;的异常.当然了,如果你没有正确配置,这个 异常仍然会被抛出的.有些邮件服务系统是不需要验证发件人的授权的,所以可以很简单的使用 Session session = Session.getDefaultInstance(props, null); 而不必使用 props.put(&mail.smtp.auth&, &true&); MyAuthenticator myauth = new MyAuthenticator(&你自己的电子信箱&, &你自 己的信箱密码&); Session session = Session.getDefaultInstance(props, myauth);就可以发送电子邮件了,这个多为一些企事业单位的内部电子信箱系统. 但是对于很多门户网站上的电邮系统,如:163,sohu,yahoo 等等,如果仍然简单的这样使 用就会抛com.sun.mail.smtp.SMTPSendFailedException: 553 authentication is required, smtp8,wKjADxuAyCAfmnZE8BwtIA==.32705S2at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.ja va:1388)at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:959)at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:583)at javax.mail.Transport.send0(Transport.java:169)at javax.mail.Transport.send(Transport.java:98) 这样的异常,要求你必须进行授权校验,它的目的就是阻止他人任意乱发邮件,也算是为了 减少垃圾邮件的出现吧.这时候,我们就要使用 props.put(&mail.smtp.auth&, &true&); MyAuthenticator myauth = new MyAuthenticator(&你自己的电子信箱&, &你自 己的信箱密码&); Session session = Session.getDefaultInstance(props, myauth); 这里还有一个特别注意的事情:在你使用 Session.getDefaultInstance 时,一定要将 props.put(&mail.smtp.auth&, &true&); 置为 true,它默认的是 false,如果你没有做这一 步,虽然你使用了 Session.getDefaultInstance(props, myauth);,你自己也确实 MyAuthenticator myauth = new MyAuthenticator(&你自己的电子信箱&, &你自己 的信箱密码&);但是它仍然会抛出 com.sun.mail.smtp.SMTPSendFailedException: 553 authentication is required, smtp8,wKjADxJA2SBrm3ZEFv0gIA==.40815S2at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.ja va:1388)at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:959)at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:583)at javax.mail.Transport.send0(Transport.java:169)at javax.mail.Transport.send(Transport.java:98) 这样的异常.我就在这一步费了好长时间,后来才发现了这个问题,很是郁闷.不过还好, 总算解决了.其实上面的做法只是比较简单的一种,也有很多其它的写法,如: Properties props = System.getProperties();可以使用 Properties props = new Properties();来代替. Transport.send(message);可以使用下面的代码来代替 String username = &你的电子信箱用户名&; String password = &你的电子信箱密码&; message.saveChanges(); // implicit with send()Transport transport = session.getTransport(&smtp&); transport.connect(&.cn&, username, password); transport.sendMessage(message, message.getAllRecipients()); transport.close(); 这种方法在同时发送多封电子邮件时比较有用.还有一些具体的相关概念,可以查看相关的官方文档,在我查询资料时,发现了一篇文章写 得相当仔细,可以加以参考:http://www./resource/article/44/44101 _JavaMail.html另附上使用 mons.mail 进行发电子邮件的示例: import mons.mail.SimpleE import mons.mail.*;public class TestCommon { public TestCommon() { } public static void main(String[] args){ SimpleEmail email = new SimpleEmail(); email.setHostName(&&);//设置使用发电子邮件的邮件服务器 try { email.addTo(&收件人信箱&); email.setAuthentication(&发件人信箱&,&发件人信箱密码&); email.setFrom(&发件人信箱&); email.setSubject(&mons.mail message&); email.setMsg(&This is a simple test of commons-email&); email.send(); } catch (EmailException ex) { ex.printStackTrace(); } } }javamail 读取完整的邮件Javamail API 虽然功能封装的比较完整,但是要写一个能正确显示复杂邮件的程序还有很多逻辑和细节要处理.下面是我最近做一个 webmail 时整理的 Servlet,基本上可以正确的读取 text,HTML,HTML 中显示图片及附件.在本servlet 中也简单处理了常见的中文问题,包括主题,附件,HTML 图片中文,email Address 中文.总体感觉有两个难点:1,附件和网页图片的抓取,需要定位数节点 nodeid,光用 partid 是不行的;2,中文分两种情况 Base64 和客户端服务器端编码不一致.本程序中实现了 3 种 displayPart()的方法,具体情况不同结合使用效率更高.本程序 还有一个未处理的地方就是我在做 nodeid 的时候最多算 10 个.当然还有其他问题欢迎指正,来出是为了给后来的初学者作个参考例子,少走弯路.import java.io.IOEimport java.io.InputSimport java.io.UnsupportedEncodingEimport java.util.HashMimport javax.mail.Fimport javax.mail.Mimport javax.mail.MessagingEimport javax.mail.Mimport javax.mail.Pimport javax.mail.Simport javax.mail.internet.InternetAimport javax.mail.internet.MimeUimport javax.servlet.ServletEimport javax.servlet.ServletOutputS import javax.servlet.http.HttpServletRimport javax.servlet.http.HttpServletRimport javax.servlet.http.HttpSimport chunwei.mail.Limport chunwei.mail.MailUserD/*** Servlet implementation class for Servlet: MailServlet* Author: luchunwei Email: */public class MailNode extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {nodeid=&&;node=&0&;currentnodeid=0;url=request.getRequestURL().toString(); HttpSession ses=request.getSession();MailUserData mud=(MailUserData)ses.getAttribute(&mud&);ServletOutputStream out=response.getOutputStream();response.setContentType(&text/charset=GB2312&);int msgid=-1,partid=-1;//msgdi:邮件编号;partid:MultiPart Message 中 part 的编号.String partname= //图片或附件的文件名String nodepara=//节点编号,如 1-2-1-0, 他以便层层剥入if (request.getParameter(&msgid&)!=null)msgid=Integer.parseInt(request.getParameter(&msgid&));msgidStr=&msgid=&+if (request.getParameter(&partid&)!=null)partid=Integer.parseInt(request.getParameter(&partid&));if (request.getParameter(&partname&)!=null)partname=new String(request.getParameter(&partname&).getBytes(&ISO-8859-1&),&GB2312&);if (request.getParameter(&node&)!=null) nodepara=request.getParameter(&node&);System.out.println(nodepara);//System.out.println(msgid+&:&+partid+&:&+partname);if (partname!=null){//displayImagestry {displayPart(partname,response,out);} catch (MessagingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}//-------------------------- if (mud==null){Login login=new Login(&imap&,&&,-1,&user&,&password&);login.login();if (login.getResult()==1){HttpSession session = request.getSession();session.setMaxInactiveInterval(3600);session.setAttribute(&mud&,login.getMud());}mud=(MailUserData)ses.getAttribute(&mud&);}//---------------------------if (mud==null){out.print(&&error&Login First(No Session)&/error&&);} else{//Folder folder=mud.getFolder(); try {//------------------------Store store=mud.getStore();Folder folder=store.getFolder(&INBOX&);folder.open(Folder.READ_ONLY);//------------------------Message m=folder.getMessage(msgid);//if(partid==-1){if (nodepara==null){//if(!imgs.isEmpty())imgs.clear();messageHtml=&&;attachment=&&;recipients=getAllgetRecipients(m);out.print(displayMessage(request,m,partid));} else{ displayPart(m,nodepara,response,out);}} catch (MessagingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}String stdUrl=&&; String url=&&;String msgidStr=&&;String messageHtml=&&;String attachment=&&;String recipients=&&;String nodeid=&&;int currentnodeid=0;String node=&&;HashMap&String,Part& imgs=new HashMap&String,Part&();public String displayMessage(HttpServletRequest request,Part p,int partid) throws Exception{//System.out.println(&Type:&+p.getContentType());if (currentnodeid==1&&!node.endsWith(&0&)){nodeid=nodeid.substring(0,(nodeid.length()-2));}node=nodeid+ System.out.println(node);if (p.isMimeType(&multipart/*&)){nodeid+=currentnodeid+&-&;Multipart mp=(Multipart) p.getContent();int cnt=mp.getCount();String mpct=mp.getContentType().toLowerCase();for (int i=0;i&i++){if(mpct.startsWith(&multipart/alternative&)&&mp.getBodyPart(i).getContentType().toLowerCase().startsWith(&text/plain&))currentnodeid=i;displayMessage(request,mp.getBodyPart(i),i);}} if (p.isMimeType(&text/plain&)||p.isMimeType(&text/html&)){if (messageHtml==&&) {messageHtml=(String)p.getContent();//System.out.println(messageHtml);} else {messageHtml=messageHtml+&&HR/&&+(String)p.getContent();//System.out.println(messageHtml);}} else if (p.isMimeType(&message/rfc822&)) {//Nested Message//displayMessage(request,(Part)p.getContent(),partid);} else{if (node.length()&2)node=node.substring(2);System.out.println(node);String disposition=p.getDisposition(); //System.out.println(&disposition:&+disposition);if (disposition!=null&&disposition.equalsIgnoreCase(Part.ATTACHMENT)){String filename=getFileName(p);//imgs.put(filename,p);//attachment 全部放入内存,会造成内存膨胀;若及时清空又造成 Back 回来的页面访问不到 Attachment//attachment+=&,&+&&a href='&+url+&/&+filename+&?&+msgidStr+&&partid=&+partid+&'&&+filename+&&/a&&;attachment+=&,&+&&a href='&+url+&/&+filename+&?&+msgidStr+&&node=&+node+&'&&+filename+&&/a&&;//attachment+=&,&+&&a href='&+url+&/&+filename+&?&+&&partname=&+getFileName(p)+&'&&+filename+&&/a&&;//System.out.println(attachment);} else{//if(disposition!=null&&disposition.equalsIgnoreCase(Part.INLINE)){if (getCid(p)!=null){//System.out.println(&Enter Replace&);imgs.put(getFileName(p),p);//String uri=url+&?&+msgidStr+&&partid=&+ String uri=url+&?&+msgidStr+&&node=&+//String uri=url+&?&+&&partname=&+getFileName(p);String t=messageHtml.substring(messageHtml.indexOf(getCid(p))-1);if (!(t.startsWith(&\&&)||t.startsWith(&\'&))){uri=&'&+uri+&'&;}messageHtml=messageHtml.replace(getCid(p),uri);//System.out.println(&cid:&+getCid(p));//System.out.println(uri);}}}return messageHtml+&attachhncwx=&+attachment+}public void displayPart(Message m,String node,HttpServletResponse response,ServletOutputStream out) throws MessagingException, IOException{Part part = getPart(m,node);String sct = part.getContentType();response.setContentType(sct);outPut(part,out);}private Part getPart(Part m, String nodes) throws NumberFormatException, MessagingException, IOException {if (node==null)String node=nodes.substring(0,1);System.out.println(nodes+& : &+node);int nid=Integer.parseInt(node);if (m.getContent()==null)System.out.print(&no content&);Part p=((Multipart)m.getContent()).getBodyPart(nid);if (nodes.length()&2)nodes=nodes.substring(2);else { if (nodes.length()==1)nodes=&&;}if (nodes.length()&0)p=getPart(p,nodes);}public void displayPart(String partname,HttpServletResponse response,ServletOutputStream out) throws MessagingException, IOException{//System.out.println(imgs.keySet()+&:&+partname);Part part=imgs.get(partname);String ct=part.getContentType();if (ct!=null)response.setContentType(ct);//=====Start push Stream into outInputStream in=part.getInputStream();ByteArrayOutputStream bos=new ByteArrayOutputStream();byte [] buffer=new byte[8192];int count=0; while ((count=in.read(buffer))&=0) bos.write(buffer,0,count);in .close();try{out.write(bos.toByteArray());out.flush();} catch(Exception e){}out.close();//=====End}public void displayPart(Message m,int partid,HttpServletResponse response,ServletOutputStream out) throws MessagingException, IOException{Multipart mp = (Multipart)m.getContent();Part part = mp.getBodyPart(partid);String sct = part.getContentType();// ContentType ct = new ContentType(sct); response.setContentType(sct);if (sct == null) {out.println(&invalid part&);}//=====Start push Stream into outInputStream in=part.getInputStream();ByteArrayOutputStream bos=new ByteArrayOutputStream();byte [] buffer=new byte[8192];int count=0;while ((count=in.read(buffer))&=0) bos.write(buffer,0,count);in .close();try{out.write(bos.toByteArray());out.flush(); } catch(Exception e){}out.close();//=====End}private String getFileName(Part p) throws MessagingException, UnsupportedEncodingException{//System.out.println(&filename:&);String filename=p.getFileName();if (filename==null)filename=new String(filename.getBytes(&ISO-8859-1&),&GB2312&);int indexStart=filename.toUpperCase().indexOf(&=?GB&);if (indexStart&-1){filename=filename.substring(0,indexStart)+MimeUtility.decodeText(filename.substring(indexStart));} }private String getCid(Part p) throws MessagingException{String cidraw=null,cid=String [] headers=p.getHeader(&Content-id&);if (headers!=null && headers.length&0) {cidraw=headers[0];} else{}if (cidraw.startsWith(&&&)&&cidraw.endsWith(&&&)) {cid=&cid:&+cidraw.substring(1,cidraw.length()-1);} else {cid=&cid:&+} }/*** 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同 &to&----收件人 &cc&---抄送人地址 &bcc&---密送人地址* @throws Exception*/private String getAllgetRecipients(Message m) throws Exception{return &mailaddrTo=&+getRecipients(m,&TO&)+&mailaddrCc=&+getRecipients(m,&CC&)+&mailaddrBcc=&+getRecipients(m,&BCC&);}private String getRecipients(Message m,String type) throws Exception {StringBuffer mailaddr = new StringBuffer(&&);String addtype = type.toUpperCase();InternetAddress[] address =if (addtype.equals(&TO&)) { address = (InternetAddress[]) m.getRecipients(Message.RecipientType.TO);} else if (addtype.equals(&CC&)) {address = (InternetAddress[]) m.getRecipients(Message.RecipientType.CC);} else {address = (InternetAddress[]) m.getRecipients(Message.RecipientType.BCC);}if (address != null) {for (int i = 0;i & address.i++) {String email = address[i].getAddress();if (email == null)email = &&;else {email = MimeUtility.decodeText(email); }String personal = address[i].getPersonal();if (personal == null)personal = &&;else {personal = MimeUtility.decodeText(personal);}mailaddr.append(&\&&+personal+&\& &);mailaddr.append(&&&);mailaddr.append(email);mailaddr.append(&&&);mailaddr.append(&,&);}}if (mailaddr.length()&0)mailaddr.deleteCharAt(mailaddr.length()-1); return mailaddr.toString();}private void outPut(Part part,ServletOutputStream out) throws IOException, MessagingException{//=====Start push Stream into outInputStream in=part.getInputStream();ByteArrayOutputStream bos=new ByteArrayOutputStream();byte [] buffer=new byte[8192];int count=0;while ((count=in.read(buffer))&=0) bos.write(buffer,0,count);in .close();try{out.write(bos.toByteArray());out.flush();} catch(Exception e){} out.close();//=====End}}在 JSP 中使用 JavaMail 邮件发送收 取(1)你希望在 jsp 中建立一个邮件发送收取工具吗?下面将介绍的就是在 jsp 中建立一个邮件发送收取工具.在这篇文章中你可以了解到 JavaMail API 的一些要点以及如何在 JSP 中使用它.本文中还包括了在 JSP 中使用 JavaMail 的实例.JavaMail 是 JSP 应用软件中相 当强大的 API.阅读这篇文章需要对 JSP,JavaBeans 和 JavaMail 有一定的初步了解.当然,有关于 JavaMail 的知识你可以通过阅读这篇文章 来获得.如果你对于以上三项一无所知,但你所使用的服务器支持 JSP 和 JavaMail 的话,你可以仅仅通过复制/粘贴来使用它们.什么是 JavaMailJavaMail 是 Sun 发布的用来处理 email 的 API.它可以方便地执行一些常用的邮件传输.虽然 JavaMail 是 Sun 的 API 之一,但它目前还没有被加在标准的 java 开发工具包中(Java Development Kit),这就意味着 你在使用前必须另外下载 JavaMail 文件.除此以外,你还需要有 Sun 的 JavaBeans Activation Framework (JAF).JavaBeans Activation Framework 的运行很复杂,在这里简单的说就是 JavaMail 的运行必须得依赖于它的支持.在 Windows 2000 下使用需要 指定这些文件的路径,在其它的操作系统上也类似.接下来要讲解的是这篇指南的最难理解的部分.这篇指南包括三部分:HTML 表格,关于 JavaMail,JavaMail 和 JSP 的结合.第一部分: 第一部分:HTML 表格 第一部分提供了一个最基本的基于 HTML 的 email 发送收取程序的例子.第二部分则讲述 JavaMail 的工作原理.第三部分则介绍 将 JavaMail 加入 JSP,创建一个基本的 email 发送收取程序.划分组件JSP 最重要的特性是能将整个网页划分成一些细小的组件.这里使用的组件包括:●一个用来将 email 的信息发送给 JSP 的 HTML 表格;●一个 JSP 页面用来处理和发送信件.第一步,就是创建一个 HTML 表格用来给 JSP 页面发送信息.你可以将以下的 HTML 代码复制到你的电脑上:用来发送 email 的 HTML 源代码&HTML& &BODY& &FORM action=&sendmail.jsp& method=&post&& &TABLE align=&center&& &TR& &TD width=&50%&& To:&BR&&INPUT name=&to& size=&25&& &/TD& &TD width=&50%&& From:&BR&&INPUT name=&from& size=&25&& &/TD& &/TR& &TR& &TD colspan=&2&& Subject:&BR&&INPUT name=&subject& size=&50&& &/TD& &/TR& &TR& &TD colspan=&2&& Message:&BR&&TEXTAREA name=&text& rows=25 cols=85&&/TEXTAREA& &/TD& &/TR& &/TABLE& &INPUT type=&submit& name=&cb_submit& value=& Send && &INPUT type=&reset& name=&cb_reset& value=& Clear && &/FORM& &/BODY& &/HTML&以上这段程序将创建一个包含 email 基本信息(例如:收件地址,发送地址,主题和内容)的文件.当然你可以根据你自己的需要 来决定这个文件包含那些信息.这个 HTML 文件的使用有两点要求:第一点是生成的文件必须发送给接下来将介绍的程序使用.在这个例子中就是 sendmail.jsp, 但在你使用时,必须用这个文件在系统里的 URL 来代替它;第二点是必须有空间来允许用户发送 email.邮件群发 JAVA 邮件群发 要:邮件群发是消息在 Internet 传递的最好办法,同时也是垃圾邮件的 来源.本文以使用 JAVAMAIL 为例,讨论实现大规模邮件发送的方法 和技巧. 关键字:SMTP,MIME,JAVAMAIL,群发邮件 关键字 一,引言 邮件群发是 Internet 生活中最常见的一种信息传递方式, 其传递信息的主 动性,高效率和低费用而被众多商家广泛采用.我们的电子邮箱随之充满了各 种类型的商业邮件,一般称这些商业邮件为垃圾邮件.本文笔者运用 JAVA 语 言开发了一个基于 SMTP 服务器的邮件群发软件, 在以下内容中将逐一介绍 SMTP 协议,JAVAMAIL 包,以及邮件群发程序的片段等. 二,简单邮件传输协议与 JAVAMAIL 类库 1.简单邮件传输协议(SMTP)从 1982 年起被用来在不同计算机系统间传 递电子邮件.SMTP 使用简单的 ASCII 码文本命令,命令定义长度为 4 个字符. SMTP 基本命令集及功能如表一所示. 摘 功能 从客户端打开问候信息 标识发件人 标识收件人 标识邮件开始 向终端发送邮件 执行 SEND 或 MAIL 命令 执行 SEND 或 MAIL 命令 重置 SMTP 连接 验证系统用户名 查询列表和别名 查询命令列表 不操作 终止 SMTP 连接 变换 SMTP 角色 表一 绝大多数 SMTP 系统采用一种标准的邮件报文格式,即 RFC822 来&规范& 邮件的形式.RFC822 明确的划分邮件为两个部分,一部分称为邮件头,起其作 用是标识邮件;第二部分是邮件体. 邮件头中包括: 1) Received: 用来标识将邮件从最初发送者到目的地进行中间转发的 SMTP 服务器,其中含有发信人及发信服务器真实的信息. 2)Return-path:用来标识邮件发送到目的服务器所经过的路径. 3)From:显示发信人的地址.格式为 From:user-name. 4)Date:记录邮件发送时间. 5)Destination:记录收邮件地址, 标识电子邮件的接受方地址,这些地 址是纯粹地信息,SMTP 仅通过 RCPT 命令发送信件.包括 To 主收件人,Cc 抄 送收件人,Bcc 暗抄送收件人,格式为 To/Cc/Bcc:address. 6)Resent:表示一封邮件处于某中原因需要从客户端再次发送. 2.JAVAMAIL 关于邮件操作最新包是 JavaMail1.2,有四个大类,如表二 所示. javax.mail javax.mail.event 邮件系统模型类 Javamail API 监听和事 件处理类命令 HELO MAIL RCPT DATA SEND SOML SAML RSET VRFY EXPN HELP NOOP QUIT TURNjavax.mail.internet Internet 邮件系统类 javax.mail.search JavaMail API 邮件搜索 类表二 这些类操作分别属于 mailapi.jar(文件包含核心API类),smtp.jar (实现 SMTP 协议功能),pop3.jar(实现 POP3 协议功能),imap.jar(包含 IMAP 协议功能)等四个文件.同时这四个文件都被包含在 mail.jar 中,如过 图省事的话,直接包含 mail.jar 即可. 如果要实现带附件的邮件收发功能,还需要包含 activation.jar,它提供 通过二进制数据流的形式处理 MIME 类型的访问. 程序举例 三,程序举例 1.首先是连接 SMTP 服务器,JAVAMAIL1.2 不能实现 SMTP 服务的功能,但 可以连接已有的 SMTP 服务器. //创建一个属性对象 Properties props=System.getProperties(); //创建系统属性对象 props.setProperty(&mail.transport.protocol&,&smtp&); //设置 使用 smtp 协议 props.setProperty(&mail.smtp.host&,server); //设置 SMTP 服务器 地址 props.setProperty(&mail.smtp.port&,&&+port); //设置 SMTP 端口号 props.setProperty(&mail.smtp.auth&,&true&); //SMTP 服务用户 认证 //创建一个过程对象 javax.mail.Session sess = javax.mail.Session.getDefaultInstance(props, null); 2.创建一封新邮件,一般定义该 MimeMessage 创建一个邮件对象. MimeMessage msg=new MimeMessage(sess); //创建邮件对象 msg.setSubject(&邮件群发&); //设置邮件主题 msg.setSentDate(new Date()); //设置发信日期 msg.setFrom(Address address); //设置发信人 邮件地址只要符合带有&@&符号并且使用&.&分成三段的字符串都会被 SMTP 服务器接受,发送广告邮件的商家一般都会在这里修改发信人地址,所以 我们的收件箱中看见的广告邮件显示中发信人内容一些的根本不存在邮件地址. 如果想查看真正地发信人,应该查看邮件头中 Received 的内容. //设置主收件人 msg.setRecipients(Message.RecipientType.TO,Address toaddress); //设置抄送收件人 msg.addRecipients(Message.RecipientType.CC,Address coaddress); //设置暗抄送人 msg.addRecipients(Message.RecipientType.BCC,Address bcoaddress); SMTP 允许一封邮件有多个接受者,我们可以利用这个特点,在这三个收件 人中填写多个收件人地址来提高大规模发邮件效率. 另外 Bcc 这个字段可以隐藏 收件人的地址,你有时可能发现邮件的收件人不是自己却收到了这封邮件,就是 利用了暗抄这个属性. 3.邮件体一般分为邮件正文本部分和附件部分.正文部分需要设置文本的 格式,包括 text 文本类型,messafe 报文类型,image 图象类型,video 视频类 型,audio 声音类型,application 应用程序类型,multipart 混合类型等. 如下例, String m_ //为需要添加文本内容 MimeMultipart content=new MimeMultipart(); //创建邮件体对象 if(content==null) MimeBodyPart part=new MimeBodyPart(); //创建文本部分对象 String type=&text/plain&; //文本类型默认为 text/plain if(m_body.startsWith(&&html&&) || m_body.startsWith(&&HTML&&)) type=&text/html&; //如果是网页形式的内容, 则改变 类型为 text/html part.setText(m_body); part.setHeader(&Content-Type&,type); content.addBodyPart(part); msg.setContent(content); //添加文本至邮件 中 msg.saveChanges(); //保存修改 4.如何向的邮件中添加附件,利用多用途互联网邮件扩展(MIME)协议可 以直接二进制数据添加到标准的 RFC822 邮件中.在 JAVAMAIL 中实现方法如下, S //用于存储文件名称与存放路径 if(filename!=null || filename.length()&0){ MimeBodyPart part=new MimeBodyPart();//创建 MIME 对象 DataSource fds = new FileDataSource(filename); //创建文件流 对象 part.setDataHandler(new DataHandler(fds)); part.setFileName(MimeUtility.encodeText(fds.getName())); content.addBodyPart(part); //添加二进制编码至邮件体 中 } msg.setContent(content); //添加文本至邮件中 msg.saveChanges(); //保存修改 5.邮件的基本内容设置完毕,发送 SMTP 电子邮件. Transport trans=sess.getTransport(); //创建发送对象 trans.send (msg); //发送 6.如何群发邮件,首先我们要有一个邮件地址列表,邮件地址列表可以向从 公共网站获得,也可以根据某单位名称按字典法生成,或者购买用户表.邮件地 址列表应该按行存放每个邮件地址. 发信的速度和 SMTP 的响应速度有密切的关系,所以因该充分利用一封邮件 可以有多个接受地址的条件,将邮件地址按组读入进行发送,才能提高邮件群发 地效率.下面的例子是每一封信发给 10 个邮件地址. import java.io.*; import java.net.*; import java.util.*; import javax.mail.*; import javax.activation.*; import javax.mail.internet.*; class massmail(){ try{ FileReader fis = new FileReader(&邮件列表文件&); BufferedReader dis = new BufferedReader(fis); int i=0; while((fileline = dis.readLine())!=null){ if((i%10)==0) MimeMessage msg=new MimeMessage(sess); …… if((i%10)!=0){ //多个邮件地址之间要加 &,& maillist = maillist + &,& + }else{ maillist = } i++; if((i%10)==0){ //一封邮件在暗抄地址处加 10 个收件 人 msg.addRecipients(Message.RecipientType.BCC, maillist); …… //设置邮件内容 Transport trans=sess.getTransport(); //创建发送 对象 trans.send (msg); } } fis.close(); }catch(Exception error){ System.out.println(&Exception:& + error); } //发送

我要回帖

更多关于 怎样才能群发信息 的文章

 

随机推荐