|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在性能方面,在windows平台下,.net可能是占强项,要是把.net放在sun开发的操作系统上去运行呢?根本就运行不了,.net对其它操作系统的支持也很弱,性能也可能比不上java。疾速进门择要
这篇文章先容创立基于Java的email使用程序进门常识。假设你想创立你本人的email客户端使用程序来取代Microsoft Outlook,大概创立一个基于Web的email体系来跟Hotmail叫板,那末你能够从这里入手下手。从JavaMail的一个分歧角度动身,该文给出了一个发言email客户端使用程序。
在JavaMail中,你能够找到API和实在现部分,从而用它开辟功效周全的email客户端使用程序。“email客户端使用程序”援用了Microsoft Outlook的头脑;但是,你能够写你本人的Outlook来取而代之。可是,一个email客户端程序纷歧定要驻留在一个客户端呆板上。现实上,它能够是一个在远程服务器上运转的一个servlet大概EJB,终端用户经由过程Web扫瞄器能够收发他们的email。在作者本人的宠物项目中,就利用了一个语音客户端来读取吸收出去的动静。它是作者在“TalkingJava!”中先容的设法(在前面将有更多的先容)的提炼。
如今入手下手安装和设置Javamail软件。
安装
假如你利用的是Java2企业版(J2EE)1.3,那末它已自带有JavaMail,因而不必要举行分外的安装。可是假如你利用的是Java2尺度版(J2SE)1.1.7及今后的版本,那末假如想要你的使用程序具有收发email的才能,下载并安装以下两个使用程序:
l、JavaMail
2、JavaBeansActivationFramework
安装很复杂,只需解压下载的文件,并把所包括的jar文件增加到你呆板的classpath下,以下是作者呆板上的classpath:
;C:AppsJavajavamail-1.2mail.jar;C:AppsJava
javamail-1.2mailapi.jar;C:AppsJavajavamail-1.2
pop3.jar;C:AppsJavajavamail-1.2smtp.jar;C:Apps
Javajaf-1.0.1activation.jar
mailapi.jar文件包括中心API类,而pop3.jar和smtp.jar文件包括各自的email协定完成部分。(在这篇文章中我们不利用imap.jar文件)。能够以为完成部分跟JDBC(Java数据库毗连)驱动程序类似,不外它是用于动静体系而不是用于数据库罢了。至于mail.jar文件,它包括了下面的每个jar文件,因而,你能够在你的classpath中只包括mail.jar和activation.jar文件。
Activation.jar文件同意你经由过程二进制数据流的情势处置MIME范例的会见。在前面“不单单能够发送一般文本”这一部分会讲到DataHandler类,你能够在那找到相干信息。
至于纪录,本文的余下部分没有对API做周全的解说;不外你能够学着往做一做。假如你想更多的懂得API信息,你能够检察每一个下载包中的PDF文件和Javadoc。
一旦你已安装了这个软件,那末你必要晓得你的email帐户情形以便运转上面的这个例子。你必要晓得你的ISP的SMTP服务器名和POP服务器名,你的email帐户登录名和你的邮箱暗码。图1暗示的是作者在Microsoft Outlook中利用的具体情形:
经由过程SMTP发送email
第一个例子告知你如何经由过程SMTP发送一个基础的email动静。鄙人面,你将找到SimpleSender类,它从命令行读取你的动静,然后挪用一个独自的办法send(…)来发送它们:
packagecom.lotontech.mail;
importjavax.mail.*;
importjavax.mail.internet.*;
importjava.util.*;
/**
*Asimpleemailsenderclass.
*/
publicclassSimpleSender
{
/**
*Mainmethodtosendamessagegivenonthecommandline.
*/
publicstaticvoidmain(Stringargs[])
{
try
{
StringsmtpServer=args[0];
Stringto=args[1];
Stringfrom=args[2];
Stringsubject=args[3];
Stringbody=args[4];
send(smtpServer,to,from,subject,body);
}
catch(Exceptionex)
{
System.out.println("Usage:javacom.lotontech.mail.SimpleSender"
+"smtpServertoAddressfromAddresssubjectTextbodyText");
}
System.exit(0);
}
下一步,以下所示运转SimpleSender,用你本人的SMTP交换你email设置中的smtp.myISP.net:
javacom.lotontech.mail.SimpleSendersmtp.myISP.netbill@lotontech.com
ben@lotontech.com"Hello""JusttosayHello."
假如它能一般事情起来的话,在吸收端你将看到如图2所示的内容
从SimpleSender读取的动静
SimpleSender类次要由Send(…)办法完成。其代码以下:
/**
*"send"methodtosendthemessage.
*/
publicstaticvoidsend(StringsmtpServer,Stringto,Stringfrom
,Stringsubject,Stringbody)
{
try
{
Propertiesprops=System.getProperties();
//--AttachingtodefaultSession,orwecouldstartanewone--
props.put("mail.smtp.host",smtpServer);
Sessionsession=Session.getDefaultInstance(props,null);
//--Createanewmessage--
Messagemsg=newMimeMessage(session);
//--SettheFROMandTOfields--
msg.setFrom(newInternetAddress(from));
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to,false));
//--WecouldincludeCCrecipientstoo--
//if(cc!=null)
//msg.setRecipients(Message.RecipientType.CC
//,InternetAddress.parse(cc,false));
//--Setthesubjectandbodytext--
msg.setSubject(subject);
msg.setText(body);
//--Setsomeotherheaderinformation--
msg.setHeader("X-Mailer","LOTONtechEmail");
msg.setSentDate(newDate());
//--Sendthemessage--
Transport.send(msg);
System.out.println("MessagesentOK.");
}
catch(Exceptionex)
{
ex.printStackTrace();
}
}
}
起首,请注重,你失掉一个emailsession(java.mail.Session),没有它你甚么都做不了。在这个案例中,你挪用了Sesion.getDefultInstance(…)来失掉一个共享session,别的的桌面使用程序也能够利用它;你也能够经由过程Session.getInstance(…)办法创建一个新的session,它关于你的使用程序来讲是独一的。然后我们可以证实email客户端使用程序对每一个用户来讲,其利用办法都是一样的,好比它能够是一个用servlet完成的基于Web的email体系。
创建一个session必要设置一些属性;假如你经由过程SMTP发送动静,那末最少必要设置mail.smtp.host属性。在API文档中你能够找到别的的属性。
如今你有了一个session,创立了一个动静。在这个例子中,你就能够设置email地点信息、主题、注释了,一切这些都取自于命令行。你也能够设置一些头信息,包含日期等,而且你还能够指定复制(CC)的收件人。
最初,你经由过程javax.mail.Transport类发送动静。假如你想晓得我们的emailsession,请看前面的动静机关器。
不单单能够发送一般文本
javax.mail.Message(承继javax.mail.Part接口)类中的setText(…)办法把动静内容赋给所供应的字符串,把MIME设置为text/plain。
可是,你不单单能够发送一般文本,你还能够经由过程setDateHandler(…)办法发送别的范例的内容。在年夜多半情形下,你能经由过程接纳“别的范例内容”来指定文件附件,好比Word文档,可是风趣的是,你反省这里的代码发明它发送一个Java序列化的对象:
ByteArrayOutputStreambyteStream=newByteArrayOutputStream();
ObjectOutputStreamobjectStream=newObjectOutputStream(byteStream);
objectStream.writeObject(theObject);
msg.setDataHandler(newDataHandler(newByteArrayDataSource(byteStream.toByteArray(),"lotontech/javaobject")));
在javax.mail.*包布局中你大概找不到DataHandler类,由于它属于JavaBeansActivationFramework(JAF)的javax.activation包。JAF供应处置数据内容范例的机制,这类机制次要是针对Internet内容而言,也即MIME范例。
假设你已实验过了以上的代码,经由过程email来发送一个Java对象,你大概碰着定位ByteArrayDataSource类的成绩,由于要末是mail.jar要末是activation.jar未被包括在程序内里。能够到JavaMail demo目次下往查找一下。
至于你一入手下手就感乐趣的附件,你能够在DataHandler的机关器中创建一个javax.activation.FileDataSource实例来完成。固然,你不成能独自发送一个文件;它能够作为一个文本动静的附件发送。大概你必要了解多部分动静的观点,如今,我在吸收email的情况下为你先容这个观点。
经由过程POP3承受email
在后面,我先容了由javax.mail.Message完成的javax.mail.Part接口。我如今将注释它的动静部分,它在这个例子中很主要。我们先看图3。
mail.Part接口的UML图
图3暗示在后面例子中创建的一个Message,它既能够是一个动静,也能够是一个动静部分,由于它完成了Part接口。关于任何部分,你都能失掉它的内容(任何Java对象),而且在发送的是一个复杂文本动静的情形下,内容对象多是一个String。关于多部分动静,内容多是范例Multipart,由此我们能够失掉独自的注释部分,它自己就完成了Part接口
实践上,当你看过SimpleReceiver类的代码以后,你会发明统统都变得很开阔爽朗。我们用三部份内容来先容SimpleReceiver类:第一部分,类的界说和从命令行猎取毗连细节信息的main()办法;第二部分,捕捉和检察出去动静的receive()办法;第三部分,打印头信息和每一个动静内容的printMessage()办法。
上面是第一部分:
packagecom.lotontech.mail;
importjavax.mail.*;
importjavax.mail.internet.*;
importjava.util.*;
importjava.io.*;
/**
*Asimpleemailreceiverclass.
*/
publicclassSimpleReceiver
{
/**
*Mainmethodtoreceivemessagesfromthemailserverspecified
*ascommandlinearguments.
*/
publicstaticvoidmain(Stringargs[])
{
try
{
StringpopServer=args[0];
StringpopUser=args[1];
StringpopPassword=args[2];
receive(popServer,popUser,popPassword);
}
catch(Exceptionex)
{
System.out.println("Usage:javacom.lotontech.mail.SimpleReceiver"
+"popServerpopUserpopPassword");
}
System.exit(0);
}
如今我们利用命令行来运转它(记着用你的email设置交换命令行参数):
javacom.lotontech.mail.SimpleReceiverpop.myIsp.netmyUserNamemyPassword
receive()办法从main()办法中挪用,它顺次翻开你的POP3信箱反省动静,每次都挪用printMessage()。代码以下:
/**
*"receive"methodtofetchmessagesandprocessthem.
*/
publicstaticvoidreceive(StringpopServer,StringpopUser
,StringpopPassword)
{
Storestore=null;
Folderfolder=null;
try
{
//--Getholdofthedefaultsession--
Propertiesprops=System.getProperties();
Sessionsession=Session.getDefaultInstance(props,null);
//--GetholdofaPOP3messagestore,andconnecttoit--
store=session.getStore("pop3");
store.connect(popServer,popUser,popPassword);
//--Trytogetholdofthedefaultfolder--
folder=store.getDefaultFolder();
if(folder==null)thrownewException("Nodefaultfolder");
//--...anditsINBOX--
folder=folder.getFolder("INBOX");
if(folder==null)thrownewException("NoPOP3INBOX");
//--Openthefolderforreadonly--
folder.open(Folder.READ_ONLY);
//--Getthemessagewrappersandprocessthem--
Message[]msgs=folder.getMessages();
for(intmsgNum=0;msgNum<msgs.length;msgNum++)
{
printMessage(msgs[msgNum]);
}
}
catch(Exceptionex)
{
ex.printStackTrace();
}
finally
{
//--Closedownnicely--
try
{
if(folder!=null)folder.close(false);
if(store!=null)store.close();
}
catch(Exceptionex2){ex2.printStackTrace();}
}
}
请注重:你从session中失掉一个POP3动静存储封装器,然后利用最后在命令行上键进的mail设置跟它毗连。
一旦毗连乐成,你就失掉了一个默许文件夹的句柄,在这里利用的是INBOX文件夹,它保留了出去的动静。你能够翻开这个只读的INBOX信箱,然后一个一个的读作废息。
别的,你大概想晓得是不是你可以以写的体例翻开这个INBOX信箱。假如你想为这些动静做标志大概从服务器上删除,你能够做失掉。不外在我们的这个例子中,你只能检察动静。
最初,在下面的代码中,你做到了当检察终了后封闭文件夹和动静存储,然后留下printMessage()办法来完成这个类的残剩部分。
打印动静
在这一部分,很有需要会商后面提到的javax.mail.Part接口。
上面的代码让你分明如何隐含地把动静转换为它的Part接口而且把它赋给messagePart变量。关于只要一部分的动静,你如今必要打印一些信息。
假设挪用messagePart.getContent()来天生一个Multipart实例,你晓得你正在处置一个多部分动静;在这类情形下,你正在经由过程getBodyPart(0)来失掉第一个多部分动静而且打印它。
固然你还要晓得是不是你已失掉了这个动静自己,仍是仅仅是动静注释的第一部分。只要当内容是一般文本大概HTML时,你才能够打印该动静,这是经由过程一个InputStream来完成的。
/**
*"printMessage()"methodtoprintamessage.
*/
publicstaticvoidprintMessage(Messagemessage)
{
try
{
//Gettheheaderinformation
Stringfrom=((InternetAddress)message.getFrom()[0]).getPersonal();
if(from==null)from=((InternetAddress)message.getFrom()[0])
.getAddress();
System.out.println("FROM:"+from);
Stringsubject=message.getSubject();
System.out.println("SUBJECT:"+subject);
//--Getthemessagepart(i.e.themessageitself)--
PartmessagePart=message;
Objectcontent=messagePart.getContent();
//--oritsfirstbodypartifitisamultipartmessage--
if(contentinstanceofMultipart)
{
messagePart=((Multipart)content).getBodyPart(0);
System.out.println("[MultipartMessage]");
}
//--Getthecontenttype--
StringcontentType=messagePart.getContentType();
//--Ifthecontentisplaintext,wecanprintit--
System.out.println("CONTENT:"+contentType);
if(contentType.startsWith("text/plain")||contentType.startsWith("text/html"))
{
InputStreamis=messagePart.getInputStream();
BufferedReaderreader=newBufferedReader(newInputStreamReader(is));
StringthisLine=reader.readLine();
while(thisLine!=null)
{
System.out.println(thisLine);
thisLine=reader.readLine();
}
}
System.out.println("-----------------------------");
}
catch(Exceptionex)
{
ex.printStackTrace();
}
}
}
为了复杂起见,我假定动静自己大概动静注释的第一部分是能够打印的。关于真实的使用软件,大概你想要顺次反省动静注释的每部分,而且对每部分接纳响应的举动-打印大概是保留到磁盘,这取决于内容的范例。
当你从动静存储中失掉每一个动静时,你实践上已失掉了一个轻量级的封装器。数据内容的猎取是每请求一次就读取一次-这关于你只想下载动静头时很有效。
SimpleReceiver测试
让我们对SimpleReceiver做一次测试。为了让它有工具能够吸收,我发送图4所示的动静(注重:动静由文本和一个附件构成)
用于SimpleReceiver的测试动静
一旦吸收到动静,就把该动静以为是一个多部分动静。打印的文本以下:
FROM:TonyLoton
SUBJECT:Number1
[MultipartMessage]
CONTENT:text/plain;
charset="iso-8859-1"
Attachment1
fromTonyLoton.
-----------------------------
把你的动静送进来
为了风趣一点,而且申明JavaMail APIs的一个新奇的用法,我如今扼要先容一下我的发言email项目。在做这个实验之前你必要失掉lotontalk.jar文件,并把它加到你的classpath中往,增加办法以下:
setCLASSPATH=%CLASSPATH%;lotontalk.jar
你也必要在SimpleReceiver类中两个中央做代码修正。起首在receive()办法内里,把以下代码:
//--Getthemessagewrappersandprocessthem--
Message[]msgs=folder.getMessages();
for(intmsgNum=0;msgNum<msgs.length;msgNum++)
{
printMessage(msgs[msgNum]);
}
交换为:
//--Getthemessagewrappersandprocessthem--
Message[]msgs=folder.getMessages();
for(intmsgNum=0;msgNum<msgs.length;msgNum++)
{
printMessage(msgs[msgNum]);
speakMessage(msgs[msgNum]);
}
如今增添以下的新办法speakMessage(),它与最后的printMessage()办法类似。
/**
*"speakMessage",atalkingversionofprintMessage().
*/
publicstaticvoidspeakMessage(Messagemessage)
{
Stringspeech="";
try
{
com.lotontech.talk.LOTONtalkspeaker=newcom.lotontech.talk.LOTONtalk();
Stringfrom=((InternetAddress)message.getFrom()[0]).getPersonal();
if(from==null)from=((InternetAddress)message.getFrom()[0]).getAddress();
speech=speech+"from"+from+",";
Stringsubject=message.getSubject();
speech=speech+"subject"+subject+",";
//--Getthemessagepart(i.e.,themessageitself)--
PartmessagePart=message;
Objectcontent=messagePart.getContent();
//--...oritsfirstbodypartifitisamultipartmessage--
if(contentinstanceofMultipart)
messagePart=((Multipart)content).getBodyPart(0);
StringcontentType=messagePart.getContentType();
if(contentType.startsWith("text/plain")||contentType.startsWith("text/html"))
{
InputStreamis=messagePart.getInputStream();
BufferedReaderreader=newBufferedReader(newInputStreamReader(is));
StringthisLine=reader.readLine();
while(thisLine!=null)
{
speech=speech+thisLine+".";
thisLine=reader.readLine();
}
//--SPEAK--
speaker.speak(speech,true);
}
}
catch(Exceptionex)
{
ex.printStackTrace();
}
}
由于在措辞之前,你正在把全部动静堆集到一个字符串中,以是这个计划大概只合适小的动静。作为一种选择,你能够读一行然后再讲一行。
固然,我不成能把了局显现给你看,因而你必需亲身来做实行。
你还能够做一些小的实验,固然不是在这个实验中,来发明语音分解的一些风趣的特性:如何处置数字,和如何把全体年夜些的单词设想成只取首字母的缩写词,然后一个一个字母地把它们拼出来。
结论
我们已经由过程对发送和吸收email动静的使用程序的各个基础机关块分离解说,触及到了收发email的各个方面。假如你是第一次打仗JavaMail,是否是发明在使用程序中收发email不是一件坚苦的事变。
但是对于JAVA技术类的学习,我觉得大课堂反而会影响自身独立思考的过程,因为上课的时候,老师讲课的速度很快为了不遗漏要点,通常会仔细的听, |
|