java mail学习笔记4——Message类详解

    xiaoxiao2021-12-13  22

    Message类

    在Java Mail 中Message类是所有电子邮件的的超类它的定义如下: public abstract class javax.mail.Message implements javax.mail.Part 1.标准的Java Mail API中有一个Message的子类:MimeMessage,它可用于电子邮件和Usenet新闻消息。除此之外,其他厂商可以自由扩展Message来满足自身需求。 Message类主要声明了定义大多数消息公共属性的抽象获取和设置方法。这些属性包括 (1)消息地址 (2)消息接收方 (3)消息主题和主体等 可以将这些属性视为包含消息的信封。 2.Message还实现了Part接口。Part接口用于处理消息的主体

    创建消息

    Message类有三个构造函数可以创建消息:

    protected Message();

    protected Message(Folder folder,int messageNumber);

    protected Message(Session);

    其中,第二个方法的参数说明如下:

    folder - 包含文件夹 msgnum - 在这个文件夹中消息的序列号

    回复消息

    如果已经有了一个Message对象,要创建一个新的Message对象,可以使用: public abstract Message reply(boolean replyAll)throws MessagingException 此方法用加了前缀“Re:”的相同主题和最初消息的发送方地址创建一个新的Message对象。如果参数为true, 消息会寻址到最初消息的所有接收方。消息的内容为空。如果要引用初始消息,就必须自己来完成这个工作。

    From地址

    下面四个方法用来获得和设置消息的“From”

    public abstract Address[] getFrom() throws MessagingException public abstract void setFrom() throws MessagingExceptionpublic abstract void addFrom(Address[] addresses) throws MessagingExceptionpublic abstract void addFrom(Address[] addresses) throws MessagingException

    Reply-to地址

    有些消息包含一个Reply-to,指示回复消息应当发送到与发送消息不同的地址。有两个方法可以设置和获得这些地址:

    public Address[] getReplyTo() throws MessagingException

    Get the addresses to which replies should be directed.

    public void setReplyTo(Address[] addresses) throws MessagingException Set the addresses to which replies should be directed

    接收方地址

    消息的发送方一般只存在于From:首部中,而消息的接收方却分为To,Cc,Bcc三个字段。在Java Mail中,这三个字段分别是:

    Message.RecipientType.TO

    Message.RecipientType.CC

    Message.RecipientType.BCC

    获取Message的接收方地址有两个方法:

    public abstract Address[] getRecipients(Message.RecipientType type) throws MessagingException public Address[] getAllRecipients() throws MessagingException

    消息主题

    主要有两个方法:

    public abstract void setSubject(String subject) throws MessagingException public abstract String getSubject() throws MessagingException

    消息日期

    消息还有发送、接收日期:

    public abstract Date getSentDate() throws MessagingException public abstract void setSentDate(Date date) throws MessagingException public abstract Date getReceivedDate() throws MessagingException [java]  view plain  copy package com.mail;      import java.util.Date;   import java.util.Properties;      import javax.mail.*;   import javax.mail.internet.InternetAddress;      public class HeaderClient {          /**       * @param args       */       public static void main(String[] args) {           try {               Properties props=new Properties();                 props.setProperty("mail.transport.protocol""pop3");                 props.setProperty("mail.host""pop3.sina.com");               Session session=Session.getDefaultInstance(props,                        new Authenticator()                 {                        protected PasswordAuthentication getPasswordAuthentication()                     {                         return new PasswordAuthentication("yananlemon@sina.com","111111");                     }                 }  );                  //连接服务器,并打开文件夹                Store store=session.getStore("pop3");                     store.connect("pop3.sina.com""yananlemon@sina.com""1111111");               Folder folder=store.getFolder("INBOX");               if(folder==null){                   System.out.println("Folder not found!");                   System.exit(1);               }               folder.open(Folder.READ_ONLY);               //从服务器获取消息               Message[] ms=folder.getMessages();               for(int i=0;i<ms.length;i++){                   System.out.println("--------------Message"+(i+1)+"---------------");                   String from =InternetAddress.toString(ms[i].getFrom());                   if(from!=null){                       System.out.println("消息来自:"+from);                   }                   String to=InternetAddress.toString(ms[i].getRecipients(Message.RecipientType.TO));                   if(to!=null){                       System.out.println("消息去往:"+to);                   }                   String replyTo=InternetAddress.toString(ms[i].getReplyTo());                   if(replyTo!=null){                       System.out.println("消息回复给:"+replyTo);                   }                   String cc=InternetAddress.toString(ms[i].getRecipients(Message.RecipientType.CC));                   if(cc!=null){                       System.out.println("消息抄送:"+cc);                   }                   Date sent=ms[i].getSentDate();                   if(sent!=null){                       System.out.println("消息发送时间::"+sent);                   }                   String subject=ms[i].getSubject();                   if(subject!=null){                       System.out.println("消息主题:"+subject);                   }                   Date received=ms[i].getReceivedDate();                   if(received!=null){                       System.out.println("消息接收时间:"+received);                   }                   System.out.println();                  }               folder.close(false);               store.close();           } catch (MessagingException e) {               e.printStackTrace();           }       }      }   下面是输出:

    标志

    标志类代表了消息上的标志集合。它是系统标志的预定义的组成,也包括用户自定义的标志。

    在Message中与标志有关的方法如下:

    public abstract Flags getFlags() throws MessagingException public boolean isSet(Flags.Flag flag) throws MessagingException public void setFlag(Flags.Flag flag, boolean set) throws MessagingException public abstract void setFlags(Flags flag, boolean set) throws MessagingException 其中,最后两个方法用于设置或取消设置(取决于第二个参数)由第一个参数指示的标志,例如:

    [java]  view plain  copy ms[i].setFlag(Flags.Flag.DELETED,true)   上面一行代码会删除消息,这只是标记消息已经删除,它并没有实际从服务器上清除其文件。在消息被清除前,

    仍然可以将Flags.Flag.DELETED设回false来完成取消删除。

    Flags类包括一个static的Flag字段,该字段预定义了七个常量:

    static Flags.FlagANSWERED            This message has been answered.static Flags.FlagDELETED            This message is marked deleted.static Flags.FlagDRAFT            This message is a draft.static Flags.FlagFLAGGED            This message is flagged.static Flags.FlagRECENT            This message is recent.static Flags.FlagSEEN            This message is seen.static Flags.FlagUSER            A special flag that indicates that this folder supports user defined flags.

    值得注意的是,pop3服务器不会报告标志,只有存储并转发消息的协议(如IMAP协议)才会报告标志。

    下面的代码用来显示电子邮件的标志信息:

    [java]  view plain  copy //测试标志                   if(ms[i].isSet(Flags.Flag.DELETED)){                       System.out.println("deleted!");                   }                   if(ms[i].isSet(Flags.Flag.ANSWERED)){                       System.out.println("answered!");                   }                   if(ms[i].isSet(Flags.Flag.DRAFT)){                       System.out.println("draft!");                   }                   if(ms[i].isSet(Flags.Flag.FLAGGED)){                       System.out.println("flagged!");                   }                   if(ms[i].isSet(Flags.Flag.RECENT)){                       System.out.println("recent!");                   }                   if(ms[i].isSet(Flags.Flag.SEEN)){                       System.out.println("seen!");                   }                   if(ms[i].isSet(Flags.Flag.USER)){                       //预先不知道用户标志是什么                       //所以它们返回字符串数组                       String[] userFlags=ms[i].getFlags().getUserFlags();                       for(int k=0;i<userFlags.length;k++){                           System.out.println("用户标志:"+userFlags[i]);                                                  }                   }  

    搜索

    如果服务器支持搜索(很多IMAP服务器支持,而大多数POP服务器不支持),就很容易在文件夹中搜索满足条件的消息。

    Message提供了搜索邮件的接口:

    [java]  view plain  copy public boolean match(SearchTerm term)                 throws MessagingException   它将根据SearchTerm类型的对象来搜索Message,返回值告诉调用者是否搜索到了满足条件的Message。

    SearchTerm是一个抽象类,它的常用子类可以分为:

    组合搜索相关: AndTerm类 ComparisonTerm类 NotTerm类 OrTerm类 具体条件相关: AddressTerm类 FromTerm类 SentDateTerm类等等 下面例子搜索了内容包括了“test”的邮件

    [java]  view plain  copy import java.util.Date;   import java.util.Properties;      import javax.mail.internet.InternetAddress;   import javax.mail.internet.MimeUtility;   import javax.mail.search.BodyTerm;   import javax.mail.search.SearchTerm;   import javax.mail.*;   public class SearchMailTest {          /**       * @param args       */       public static void main(String[] args) {            try {                     Properties props=new Properties();                       props.setProperty("mail.transport.protocol""imap");                       props.setProperty("mail.host""imap.sina.com");                     Session session=Session.getDefaultInstance(props,                              new Authenticator()                       {                                    protected PasswordAuthentication getPasswordAuthentication()                           {                               return new PasswordAuthentication("yananlemon@sina.com","******");                           }                       }  );                              //连接服务器,并打开文件夹                      Store store=session.getStore("imap");                           store.connect("imap.sina.com""yananlemon@sina.com""******");                     Folder folder=store.getFolder("INBOX");                     if(folder==null){                         System.out.println("Folder not found!");                         System.exit(1);                     }                     folder.open(Folder.READ_WRITE);                     //从服务器获取消息                     SearchTerm search= new BodyTerm("test");                   Message[] ms=folder.search(search);                   System.out.println("搜索到"+ms.length+"封符合条件的邮件,正在打印.....");                   for(int i=0;i<ms.length;i++){                         System.out.println("--------------Message"+(i+1)+"---------------");                         String from =InternetAddress.toString(ms[i].getFrom());                         if(from!=null){                             from=MimeUtility.decodeText(from);                           System.out.println("消息来自:"+from);                         }                         String to=InternetAddress.toString(ms[i].getRecipients(Message.RecipientType.TO));                         if(to!=null){                             to=MimeUtility.decodeText(to);                           System.out.println("消息去往:"+to);                         }                         String replyTo=InternetAddress.toString(ms[i].getReplyTo());                         if(replyTo!=null){                            replyTo=MimeUtility.decodeText(replyTo);                           System.out.println("消息回复给:"+replyTo);                         }                         String cc=InternetAddress.toString(ms[i].getRecipients(Message.RecipientType.CC));                         if(cc!=null){                             System.out.println("消息抄送:"+cc);                         }                         Date sent=ms[i].getSentDate();                         if(sent!=null){                             System.out.println("消息发送时间::"+sent);                         }                         String subject=ms[i].getSubject();                         if(subject!=null){                           subject=MimeUtility.decodeText(subject);                           System.out.println("消息主题:"+subject);                         }                         Date received=ms[i].getReceivedDate();                         if(received!=null){                             System.out.println("消息接收时间:"+received);                         }                         System.out.println("消息内容:");                       if(ms[i].isMimeType("multipart/*")){                           Multipart mp=(Multipart) ms[i].getContent();                           int bodyNum=mp.getCount();                           for(int k=0;k<bodyNum;k++){                               if(mp.getBodyPart(k).isMimeType("text/html")){                                   String content=(String) mp.getBodyPart(k).getContent();                                   System.out.println(content);                               }                           }                       }else{                           System.out.println("不支持的邮件类型!");                       }                            }                     folder.close(false);                     store.close();                 } catch (Exception e) {                     e.printStackTrace();                     System.exit(1);               }        }      }  

    Part接口

    Message和BodyPart都实现了Part接口。每个Message都是一个Part,但有些Part可能包含其他部分。Part接口声明了三种方法:

    获取和设置部分属性的方法

    获取和设置部分首部的方法

    获取和设置部分内容的方法

    部分属性是类似消息大小或接收日期的内容,其细节未在消息首部中显示指定;与之相反,首部则是包含在部分前面的名-值对;部分

    的内容是消息传输的实际数据。

    首部

    Java mail API 定义了五个部分属性:

    size:部分的字节大小

    line count:部分的行数

    description:部分的简短文本概括说明

    desposition:标示部分是否为附件或者是否应当在内部显示

    file name:附件的文件名

    不是所有部分都有所有属性。例如,不表示附件的部分不可能有filename属性。每个属性都映射到一个获取它的方法,例如:

    String getDisposition() throws MessagingException int getSize() throws MessagingExceptionint getLineCount() throws MessagingException String getFileName() throws MessagingExceptionString getDescription() throws MessagingException

    注意:如果部分没有所请求的属性,获取方法就会返回null或者-1。

    getDisprsition()方法返回一个字符串,指示内容应当在内部显示,还是作为附件显示。返回值应当是下面三种:

    null

    Part.INLINE

    Part.ATTACHMENT

    下面的程序展示了消息首部的控制台输出:

    [java]  view plain  copy package com.mail;   import java.util.Properties;   import javax.mail.*;   public class MailAttributeTest {          /**       * @param args       */       public static void main(String[] args) {           try {                 Properties props=new Properties();                   props.setProperty("mail.transport.protocol""imap");                   props.setProperty("mail.host""imap.sina.com");                 Session session=Session.getDefaultInstance(props,                          new Authenticator()                   {                          protected PasswordAuthentication getPasswordAuthentication()                       {                           return new PasswordAuthentication("yananlemon@sina.com","1111111");                       }                   }  );                    //连接服务器,并打开文件夹                 Store store=session.getStore("imap");                   store.connect("imap.sina.com""yananlemon@sina.com""1111111");                 Folder folder=store.getFolder("INBOX");                 if(folder==null){                     System.out.println("Folder not found!");                     System.exit(1);                 }                 folder.open(Folder.READ_WRITE);                 //从服务器获取消息                 Message[] ms=folder.getMessages();               for(int i=0;i<ms.length;i++){                     System.out.println("-----------下面是Message"+(i+1)+"的属性打印------------");                     System.out.println("Message size(byte) is:"+ms[i].getSize());                   System.out.println("Message lineCount is:"+ms[i].getLineCount());                   System.out.println("Message subject is"+ms[i].getSubject());                   String desc=ms[i].getDescription();                   if(desc!=null){                       System.out.println("Message description is:"+desc);                   }                   if(ms[i].getContent() instanceof Multipart){                       //该方法只是显示了附件的名字,如果消息包含附件的话                       processMultipart(ms[i]);                   }                   System.out.println("-----------Message"+(i+1)+"的属性结束------------");               }                 folder.close(false);                 store.close();             } catch (Exception e) {                 e.printStackTrace();                 System.exit(1);           }        }          /**       * if the message contains attachment       * this method will show the name of attachment       * @param ms       * @throws Exception       */       private static void processMultipart(Message ms) throws Exception{           Multipart multipart=(Multipart) ms.getContent();           for(int k=0;k<multipart.getCount();k++){               Part part=multipart.getBodyPart(k);               String disposition=part.getDisposition();               if(disposition==null);               if(disposition.equalsIgnoreCase(Part.INLINE)){                   System.out.println("This part should be displayed inline");               }               if(disposition!=null&&disposition.equalsIgnoreCase(Part.ATTACHMENT)){                   System.out.println("This part is an attachment");                   String fileName=part.getFileName();                   if(fileName!=null){                       System.out.println("The file name of this attachment is"+fileName);                   }               }              }       }      }  

    下面是运行结果:

    内容

    每个部分都有可以表现为字节序列的内容。例如,在简单电子邮件消息的部分中,内容是消息的主体。但是在多部分消息中,内容本身

    可以包含其他部分。

    读取部分内容

    Part接口声明了两个可以确定部分的MIME内容类型的方法。

    getContentType()

    isMimeType(String mimeType)

    下面程序,显示了如何处理带有附件的多部分消息:

    [java]  view plain  copy package com.mail;   import java.io.BufferedInputStream;   import java.io.BufferedOutputStream;   import java.io.File;   import java.io.FileOutputStream;   import java.io.InputStream;   import java.io.OutputStream;   import java.util.Enumeration;   import java.util.Properties;   import javax.mail.*;   public class AllPartsClient {          /**       * @param args       */       public static void main(String[] args) {            try {                     Properties props=new Properties();                       props.setProperty("mail.transport.protocol""imap");                       props.setProperty("mail.host""imap.sina.com");                     Session session=Session.getDefaultInstance(props,                              new Authenticator()                       {                                    protected PasswordAuthentication getPasswordAuthentication()                           {                               return new PasswordAuthentication("yananlemon@sina.com","111111");                           }                       }  );                              //连接服务器,并打开文件夹                      Store store=session.getStore("imap");                           store.connect("imap.sina.com""yananlemon@sina.com""111111");                     Folder folder=store.getFolder("INBOX");                     if(folder==null){                         System.out.println("Folder not found!");                         System.exit(1);                     }                     folder.open(Folder.READ_WRITE);                     //从服务器获取消息                     Message[] ms=folder.getMessages();                   for(int i=0;i<ms.length;i++){                       System.out.println("-----------Message"+i+"begin-----------");                       //显示消息首部                       Enumeration headers=ms[i].getAllHeaders();                       while(headers.hasMoreElements()){                           Header header=(Header) headers.nextElement();                           System.out.println(header.getName()+" : "+header.getValue());                       }                       System.out.println();                       //枚举各个部分                       Object obj=ms[i].getContent();                       if(obj instanceof Multipart){                           processMultipart((Multipart)obj);                       }else{                           processPart(ms[i]);                       }                                          }                   folder.close(false);                     store.close();                 } catch (Exception e) {                     e.printStackTrace();                     System.exit(1);               }        }          private static void processPart(Part part) {           try {               String fileName=part.getFileName();               String disposition=part.getDisposition();               String contentType=part.getContentType();               if(contentType.toLowerCase().startsWith("multipart/*")){                   processMultipart((Multipart)part.getContent());               }else if((fileName==null)&&(Part.ATTACHMENT.equalsIgnoreCase(disposition))                       ||(!contentType.equalsIgnoreCase("text/plain"))){                   if(fileName!=null){                       if(fileName.endsWith(".jpg")){                                                 fileName=File.createTempFile("attachment"".jpg").getName();                                          }else{                           fileName=File.createTempFile("attachment"".txt").getName();                       }                   }                                  }               if(fileName==null){                   //可能是内部邮件                   part.writeTo(System.out);               }else{                   File f=new File(fileName);                   for(int i=1;f.exists();i++){                       String newName=fileName+"_"+i;                       f=new File(newName);                   }                   OutputStream output=new BufferedOutputStream(new FileOutputStream(f));                   InputStream input=new BufferedInputStream(part.getInputStream());                   int b;                   while((b=input.read())!=-1){                       output.write(b);                   }                   output.flush();                   output.close();                   input.close();                   System.out.println("附件"+f.getAbsolutePath()+"成功下载!");               }           } catch (Exception e) {               e.printStackTrace();           }       }          private static void processMultipart(Multipart obj) throws MessagingException {           for(int i=0;i<obj.getCount();i++){               processPart(obj.getBodyPart(i));           }       }      }   然后总结下解析邮件的流程:

    1.当得到一个Message对象时,调用它的getSubject(),getFrom()等等方法,可以得到邮件的基本信息。

    2.调用Messag.getContentType()方法来判断邮件的类型

    (1)如果邮件类型是“text/plain”或者“text/html”,说明邮件

    是纯文本,可以调用getContent()来获取邮件内容并加以显示。

    (2)如果邮件类型是“multipart/*”,表示邮件类型是复合类型,此时需将邮件的getContent()方法返回的对象

    转换成Multipart。

    3.调用Multipart的getCount()方法来检测Multipart中包含多少BodyPart对象,通过循环取出每个BodyPart对象

    在处理每个BodyPart对象时,调用它的getContent()方法确定它的类型,有三种情况:

    (1)当其类型是”text/*“表示是纯文本

    (2)当其类型是”multipart/*“需要重复2.(2)->3步骤

    (3)当其表示图片,音频等二进制内容时,可以调用getInputStream()获取原始的二进制内容。

    写入部分内容

    setText(String text)

    setContent(Object o,String type)

    writeTo(OutputStream out)

    之前的文章发送电子邮件,只是发送的简单文本而已,这对于现在的电子邮件客户端而言,是非常简单的;在创建复杂邮件之前,先要弄明白一些概念:

    1.MimeMessage :继承Message,表示整封邮件

    2.MimeBodyPart:表示邮件的一个MIME消息

    3.MimeMultipart:表示一个由多个MIME消息组合成的组合MIME消息。

    故:

    1.复杂邮件和简单文本邮件一样,都是有MimeMesage表示的

    2.对于复杂邮件,不能简单的用MimeMessage.setText 方法生成,而是要将MimeMultipart对象设置到MimeMessage对象中

    3.MimeMultipart 用来组合一个或者多个MimeBodyPart对象,其中每个MimeBodyPart对象使用MimeMultipart.addBodyPart(BodyPart part)方法

    将一个MIME消息添加到MimeMultipart对象中

    4.MimeBodyPart 对象表示的MIME消息,可能还是一个MIME组合消息,那么它的内容就需要使用一个MimeMultipart表示,这一步只是重复上述步骤而已。

    可见,不管邮件体重的数据层次关系多么复杂,我们都可以用MimeBodyPart和MimeMultipart对象的这种相互嵌套关系,来组织并封装复杂邮件。

    下面,是一个示例:

    [java]  view plain  copy package com.mail;      import java.io.File;   import java.util.Properties;   import javax.activation.DataHandler;   import javax.activation.FileDataSource;   import javax.mail.Authenticator;   import javax.mail.Message;   import javax.mail.Part;   import javax.mail.PasswordAuthentication;   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;   import javax.mail.internet.MimeMessage.RecipientType;      public class SendMail {          /**       * @param args       */       public static void main(String[] args) {           Properties props=new Properties();           props.setProperty("mail.smtp.auth""true");           props.setProperty("mail.transport.protocol""smtp");           props.setProperty("mail.host""smtp.sina.com");//smtp.sina.com           Session session=Session.getInstance(props,                    new Authenticator()           {                  protected PasswordAuthentication getPasswordAuthentication()               {                   return new PasswordAuthentication("yananlemon@sina.com","111111");               }           }           );           Message msg=new MimeMessage(session);           try {               String body="在天愿为比翼鸟,在地愿为连理枝。<br/>"+"<img src=\"cid:yanan\">";               msg.setFrom(new InternetAddress("yananlemon@sina.com"));               msg.setSubject("test");               msg.setRecipients(RecipientType.TO, InternetAddress.parse("877581150@qq.com"));//yananzx@yeah.net               MimeBodyPart contentPart=(MimeBodyPart) createContent(body,"contentFilePath");;               MimeBodyPart part=(MimeBodyPart) createAttachment("attachmentFilePath");               MimeMultipart mime=new MimeMultipart("mixed");               mime.addBodyPart(contentPart);               mime.addBodyPart(part);               msg.setContent(mime);               Transport.send(msg);               System.out.println("success");                          } catch (Exception e) {               e.printStackTrace();           }       }       static Part createContent(String content,String fileName){           MimeBodyPart contentPart=null;           try {               contentPart=new MimeBodyPart();               MimeMultipart contentMultipart=new MimeMultipart("related");               MimeBodyPart htmlPart=new MimeBodyPart();               htmlPart.setContent(content, "text/html;charset=gbk");               contentMultipart.addBodyPart(htmlPart);               MimeBodyPart gifBodyPart=new MimeBodyPart();               FileDataSource fds=new FileDataSource(new File(fileName));               gifBodyPart.setDataHandler(new DataHandler(fds));               gifBodyPart.setFileName(fds.getName());               gifBodyPart.setContentID("yanan");               contentMultipart.addBodyPart(gifBodyPart);               contentPart.setContent(contentMultipart);           } catch (Exception e) {               e.printStackTrace();           }           return contentPart;                  }       static Part createAttachment(String fileName){           Part part=new MimeBodyPart();           FileDataSource fds=new FileDataSource(new File(fileName));           try {               part.setDataHandler(new DataHandler(fds));               part.setFileName(fds.getName());           } catch (Exception e) {               e.printStackTrace();           }           return part;       }         }  
    转载请注明原文地址: https://ju.6miu.com/read-950267.html

    最新回复(0)