zoukankan      html  css  js  c++  java
  • javaMail 详解

    一、JavaMail API简介
    JavaMail API是读取、撰写、发送电子信息的可选包。

    可用它来建立如Eudora、Foxmail、MS Outlook Express一般的邮件用户代理程序(Mail User Agent,简称MUA,而非邮件传输代理MTA)。
    从另外一个角度来看,我们这些电子邮件用户日常用MUA程序来读写邮件,而MUA依赖着MTA处理邮件的递送。

    二、相关协议一览
    不依赖于协议的方式发送接收电子信息,只依赖特定协议SMTP、POP、IMAP、MIME、NNTP协议。

    1.SMTP(递送邮件机制)
    简单邮件传输协议
    SMTP服务器将邮件转发到接收者的SMTP服务器,直至最后被接收者通过POP或者IMAP协议获取。

    2.POP(获取邮件机制)
    邮局协议,目前为第3个版本POP3

    3.IMAP(多目录共享)
    接收信息的高级协议,目前版本为第4版IMAP4
    接收新信息,将这些信息递送给用户,维护每个用户的多个目录。

    4.MIME
    邮件扩展内容格式:信息格式、附件格式等等

    5.NNTP
    第三方新闻组协议

    三、安装
    1.安装JavaMail
    http://java.sun.com/products/javamail/downloads/index.html下载JavaMail
    mail.jar文件添加到CLASSPATH中

    2.安装JavaBeans Activation Framework
    http://java.sun.com/products/javabeans/glasgow/jaf.html下载JavaBeans Activation Framework
    activation.jar文件添加到CLASSPATH中

    四、初次认识JavaMail API
    1.了解我们的JavaMail环境
    A.纵览JavaMail核心类结构
    JavaMail.jar文件的一些核心类:Session、Message、Address、Authenticator、Transport、Store、Folder
    以及javax.mail.internet包中还有一些常用的子类。

    B.Session(邮件会话)
    进行收发邮件的工作都是基于这个会话的。
    Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);
    或者
    Properties props = new Properties();
    Session session = Session.getInstance(props, null);
    从上面的两个例子中不难发现,第二个参数都是null,这是因为在上面的例子中并没有使用到邮件授权(参考E)

    C.Message
    建立了Session对象后,便可以被发送的构造信息体Message抽象类
    使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型、MIME信息头的邮箱信息。
    信息头只能使用US-ASCII字符
    Message message = new MimeMessage(session);
    message.setContent("Hello", "text/plain");//非文本信息内容
    message.setText("Hello");//纯文本信息内容
    message.setSubject("First");//设置邮件主题
    message.setSentDate(Date);//设置邮件发送日期

    D.Address
    建立了Session和Message对象后,使用邮件地址Address抽象类
    使用javax.mail.internet.InternetAddress这个子类。通过传入邮件地址的字符串
    Address address = new InternetAddress("kuangye89757@163.com"); //邮件地址
    Address address = new InternetAddress("president@whitehouse.gov", "George Bush"); //带名字的邮件地址
    message.setFrom(address);//设置发信人
    message.setReplyTo(address);//同上
    message.addFrom(Address[] address);//添加多个发信人
     
    message.addRecipient(type, address)//设置收信人
    Message.RecipientType.TO//收信人
    Message.RecipientType.CC//抄送人
    Message.RecipientType.BCC//暗送人

    E.Authenticator授权者类
    使用Authenticator抽象类必须实现getPasswordAuthentication()方法(用于存储认证时要用到的用户名、密码)。
    并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类。
    Properties props = new Properties();
    Authenticator auth = new MyAuthenticator();
    Session session = Session.getDefaultInstance(props, auth);
    /**
     * 自定义邮件授权类
     * @return
     * @throws IOException
     */
    public class MyAuthenticator  extends Authenticator {
      public PasswordAuthentication getPasswordAuthentication(String param) {
    String username;
    String password;
    StringTokenizer st = new StringTokenizer(param, ",");
    username = st.nextToken();
    password = st.nextToken();
    return new PasswordAuthentication(username, password);
    }
    }


    F.Transport
    发送信息时使用Transport抽象类(实现了SMTP)
    Transport.send(MimeMessage message);
     
    或者一般用法
    当然,方法是多样的。我们也可由Session获得相应协议对应的Transport实例。并通过传递用户名、密码、邮件服务器主机名等参数建立与邮件服务器的连接,并使用sendMessage()方法将信息发送,最后关闭连接:
    session.setDebug(true);//监控邮件发送过程
    message.saveChanges(); //保存文件
    Transport transport = session.getTransport("smtp");//获取实现了SMTP协议的Transport类
    transport.connect(host, username, password);//连接服务器
    transport.sendMessage(message, message.getAllRecipients());//发送邮件给所有收件人
    transport.close();//关闭连接
     
    G.Store(存储邮件的服务器)和Folder(目录对象)
    Store store = session.getStore("pop3");
    store.connect(host, username, password);
     
    Folder folder = store.getFolder("INBOX");//POP3协议只有一个名为INBOX的Folder有效
    folder.open(Folder.READ_ONLY);//只读方式打开
    Message message[] = folder.getMessages();//获得邮件
    System.out.println(((MimeMessage)message).getContent());//邮件内容(不包含邮件头)
    System.out.println(((MimeMessage)message).writeTo());//邮件内容(含邮件头)
    folder.close(true);//若删除邮件则及时更新Folder,关闭
    store.close();//关闭


    五、使用JavaMail API
    1.发送邮件
    在获得了Session后,建立并填入邮件信息,在发送邮件之前,我们需要设置SMTP服务器:通过设置Properties的mail.smtp.host属性
     
    mail配置文件.properties
    String server=xx.xx.xx.xx(服务器)
    authUser=XXX
    authPasswd=xxxxxx
    /**
     * 获得配置文件信息
     * @return
     * @throws IOException
     */
     private static Properties getProp() throws IOException{
      //获得文件存储路径
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
      InputStream inputStream = classLoader.getResourceAsStream("mail配置文件.properties");
      Properties prop = new Properties();
      prop.load(inputStream);
      return prop;
     }
     
    private String from = ...;//发件人
    private String to = ...;//收件人
    //获取邮件发送服务器及验证用户名和密码
    Properties props=getProp();
    props.put("mail.smtp.host", host);
    //获取Session会话
    Session session = Session.getDefaultInstance(props, null);
    //创建MIMEMessage
    Message message = new MimeMessage(session);
    message.setFrom(new InternetAddress(from));
    message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
    message.setSubject("Hello JavaMail");
    message.setText("Welcome to JavaMail");
    //发送邮件
    message.saveChanges();
    Transport transport = session.getTransport("smtp");
    transport.connect(props.getProperty(“server”), props.getProperty(“authUser”), props.getProperty(“authPasswd”));
    transport.sendMessage(message, message.getAllRecipients());
    transport.close();

    2.接收邮件
    Session session = Session.getDefaultInstance(props, null);
    Store store = session.getStore("pop3");
    store.connect(props.getProperty(“server”), props.getProperty(“authUser”), props.getProperty(“authPasswd”));
    Folder folder = store.getFolder("INBOX");
    folder.open(Folder.READ_ONLY);
    Message message[] = folder.getMessages();
    for (int i=0, n=message.length; i<n; i++) {
       System.out.println(i + ": " + message[i].getFrom()[0] + " " + message[i].getSubject());
    }
    folder.close(false);
    store.close();
     
    3.删除邮件和标志
    Flags类的内部类Flag中预定义了一些标志:(POP协议不支持)
    如:Flags.Flag.DELETED   
    通过访问一个已经打开的Folder对象的getPermanetFlags()方法,它将返回当前被支持的Flags类对象。
    删除邮件时,我们可以设置邮件的DELETED标志: 
    if(Message.isSet(Flags.Flag.DELETED)){
    folder.open(Folder.READ_WRITE);
    message.setFlag(Flags.Flag.DELETED, true);//删除邮件
    folder.close(true);
    }
     
    4.回复邮件
    MimeMessage reply = (MimeMessage)message.reply(false);//不发送给发件人
    reply.setFrom(new InternetAddress("president@whitehouse.gov"));
    reply.setText("Thanks");
    Transport.send(reply);//回复邮件


    6.转发邮件
    转发邮件的过程不如前面的回复邮件那样简单,它将建立一个转发邮件,这并非一个方法就能做到。
    每个邮件是由多个部分(邮件体MimeBodyPart类对象)组成
    这些邮件体包含MimeMultiPart类对象
    复制一个邮件内容到另一个邮件的方法是复制它的DataHandler(数据处理者)
     
    Message forward = new MimeMessage(session);
    forward.setSubject("Fwd: " + message.getSubject());
    forward.setFrom(new InternetAddress(from));
    forward.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
    forward.setContent(multipart);//这里的多媒体对象通过下列方式获得
    Transport.send(forward);//转发邮件
     
    //创建邮件体对象
    BodyPart messageBodyPart = new MimeBodyPart();
    messageBodyPart.setContent(“内容”,"text/plain;charset=GB2312");
    messageBodyPart.setDataHandler(message.getDataHandler());//从邮件中获取DataHandler
     
    //创建多媒体对象
    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(messageBodyPart);
    7.使用附件
    A.发送带有附件的邮件
    建立一个完整邮件的各个邮件体部分:
    第一个部分:邮件内容文字
    第二个部分:具有DataHandler的附件
    1.若文件作为附件发送建立FileDataSource类型的附件数据源对象
    2.若URL作为附件发送建立URLDataSource类型的附件数据源对象
    Message message = new MimeMessage(session);
    message.setFrom(new InternetAddress(from));
    message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
    message.setSubject("Hello JavaMail Attachment");
     
    //第一部分(内容)
    BodyPart messageBodyPart1 = new MimeBodyPart();
    messageBodyPart1.setText("Pardon Ideas");
     
     
    //第二部分(文件附件)
    BodyPart  messageBodyPart2 = new MimeBodyPart();
    DataSource source = new FileDataSource(filename);
    messageBodyPart2.setDataHandler(new DataHandler(source));
    messageBodyPart2.setFileName(filename);
    第二种
      MimeBodyPart body = new MimeBodyPart();
       body.attachFile("d:/data.xlsx");
     
    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(messageBodyPart1);//装填第一部分
    multipart.addBodyPart(messageBodyPart2);//装填第二部分
    message.setContent(multipart);
    Transport.send(message);//发送带有附件的文件

    使用servlet实现发送带有附件的邮件注意提交页面form中对编码类型的设置应为multipart/form-data
    <form enctype="multipart/form-data"  method=post action="/myservlet"> 
     <input type="file" NAME="thefile">
     <input type="submit" VALUE="Upload">
    </form>


    B.读取邮件中的附件
    读取邮件中带有附件的邮件是多部分组成的,我们必须处理每一个部分获得邮件的内容和附件
    BodyPart类提供了getDisposition()方法获得邮件体的部署类型
    该部分是附件时返回Part.ATTACHMENTPart.INLINE
     
    //获取邮件中的多媒体
    Multipart mp = (Multipart)message.getContent();
    //循环遍历多媒体,并获取邮件体各部分
    for (int i=0, n=multipart.getCount(); i<n; i++) {
    Part part = multipart.getBodyPart(i));
    //获得邮件体的部署类型
    String disposition = part.getDisposition();
    if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT) || (disposition.equals(Part.INLINE))) {
    saveFile(part.getFileName(), part.getInputStream());
    }else if (disposition == null) {
    MimeBodyPart mbp = (MimeBodyPart)part;
    if (mbp.isMimeType("text/plain")) {
    //解析过程
    } else {
    //其他解析过程
    }
    }
    }
     
    8.处理HTML邮件
    A.发送HTML邮件
    设置邮件内容为html代码,并设置内容类型为text/html即可:
    String htmlText = "<H1>Hello</H1>" +  "<img src="http://www.jguru.com/images/logo.gif">";
    message.setContent(htmlText, "text/html"));

    请注意:
    在接收邮件时,因为JavaMail API邮件内容视为二进制流。必须使用JEditorPane

    if (message.getContentType().equals("text/html")) {
    String content = (String)message.getContent();
    JFrame frame = new JFrame();
    JEditorPane text = new JEditorPane("text/html", content);
    text.setEditable(false);
    JScrollPane pane = new JScrollPane(text);
    frame.getContentPane().add(pane);
    frame.setSize(300, 300);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.show();
    }

    B.在邮件中包含图片
    将HTML中用到的图片作为邮件附件并使用特殊的cid URL作为图片的引用(Content-ID头的引用)
    通过设置图片附件邮件体部分的header中Content-ID为一个随机字符串,
    并在HTML中img的src标记中设置为该字符串来完成了图片附件与HTML的关联。
     
    String file = ...;
    Message message = new MimeMessage(session);
    message.setSubject("Embedded Image");
    message.setFrom(new InternetAddress(from));
    message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
     
    // 创建邮件体HTML部分
    BodyPart messageBodyPart1 = new MimeBodyPart();
    String htmlText = "<H1>Hello</H1>" +   "<img src="cid:memememe">";
    messageBodyPart1.setContent(htmlText, "text/html");
     
    //创建邮件体img部分
    BodyPart  messageBodyPart2 = new MimeBodyPart();
    DataSource fds = new FileDataSource(file);
    messageBodyPart2.setDataHandler(new DataHandler(fds));
    messageBodyPart2.setHeader("Content-ID","<memememe>");
    
    
    // 创建一个关联的多媒体
    MimeMultipart multipart = new MimeMultipart("related");
    multipart.addBodyPart(messageBodyPart1);
    multipart.addBodyPart(messageBodyPart2);
    message.setContent(multipart);
    9.在邮件中搜索短语
    JavaMail API提供了过滤器机制,它被用来建立搜索短语。
    使用javax.mail.search包中的SearchTerm抽象类来定义,在定义后我们便可以使用Folder的Search()方法查找邮件:
    下面有22个不同的类(继承了SearchTerm类)供我们使用:
    AND terms 、OR terms 、NOT terms 、SENT DATE terms、CONTENT terms 、HEADER terms 
    实例:在Folder中搜索邮件主题含有“ADV”字符串或者发信人地址为friend@public.com的邮件。
    SearchTerm st =   new OrTerm(new SubjectTerm("ADV:"), new FromStringTerm("friend@public.com"));
  • 相关阅读:
    ASP.NET CORE 使用Consul实现服务治理与健康检查(2)——源码篇
    ASP.NET CORE 使用Consul实现服务治理与健康检查(1)——概念篇
    Asp.Net Core 单元测试正确姿势
    如何通过 Docker 部署 Logstash 同步 Mysql 数据库数据到 ElasticSearch
    Asp.Net Core2.2 源码阅读系列——控制台日志源码解析
    使用VS Code 开发.NET CORE 程序指南
    .NetCore下ES查询驱动 PlainElastic .Net 升级官方驱动 Elasticsearch .Net
    重新认识 async/await 语法糖
    EF添加
    EF修改部分字段
  • 原文地址:https://www.cnblogs.com/penghq/p/7607348.html
Copyright © 2011-2022 走看看