精华内容
参与话题
问答
  • JavaMail发送和接收邮件

    万次阅读 多人点赞 2009-03-09 10:40:00
    一、JavaMail概述: JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类。但它并没有包含在JDK中,而是作为JavaEE的一部分。 厂商所提供的JavaMail服务程序可以有选择地实现某些邮件...

    一、JavaMail概述:

           JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类。但它并没有包含在JDK中,而是作为JavaEE的一部分。

           厂商所提供的JavaMail服务程序可以有选择地实现某些邮件协议,常见的邮件协议包括:

    l         SMTP:简单邮件传输协议,用于发送电子邮件的传输协议;

    l         POP3:用于接收电子邮件的标准协议;

    l         IMAP:互联网消息协议,是POP3的替代协议。

    这三种协议都有对应SSL加密传输的协议,分别是SMTPSPOP3SIMAPS

    JavaMail服务提供程序之外,JavaMail还需要JAF(JavaBeans Activation Framework)来处理不是纯文本的邮件内容,这包括MIME(多用途互联网邮件扩展)、URL页面和文件附件等内容。下图描述了JavaMail的体系结构。

     

    mail.jar:此JAR文件包含JavaMail APISun提供的SMTPIMAPPOP3服务提供程序;

    activation.jar:此JAR文件包含JAF APISun的实现。

     

    二、对相关协议的回顾:

           1、介绍

           在研究 JavaMail API 的细则之前,让我们回顾用于 API 的协议。基本上,您会逐渐熟悉并喜爱的协议有四个:

     

        * SMTP

        * POP

        * IMAP

        * MIME

     

    您还将碰到 NNTP 和其它协议。理解所有协议的基本知识将有助于您理解如何使用 JavaMail API。虽然不了解这些协议您照样可以用这个 API,却不能够克服那些基础协议的局限性。如果我们精选的协议不能支持某种性能,JavaMail API 决不能魔术般的将这种性能添加上去。(您很快就会看到,在处理 POP 时这将成为一个难题。)

          

           2SMTP

           简单邮件传输协议(Simple Mail Transfer ProtocolSMTP)由 RFC 821 定义。它定义了发送电子邮件的机制。在 JavaMail API 环境中,您基于 JavaMail 的程序将和您的公司或因特网服务供应商的(Internet Service Provider'sISP'sSMTP 服务器通信。SMTP 服务器会中转消息给接收方 SMTP 服务器以便最终让用户经由 POP IMAP 获得。这不是要求 SMTP 服务器成为开放的中继,尽管 SMTP 服务器支持身份验证,不过还是得确保它的配置正确。像配置服务器来中继消息或添加删除邮件账号这类任务的实现,JavaMail API 中并不支持。

     

           3POP

           POP 代表邮局协议(Post Office Protocol)。目前用的是版本 3,也称 POP3RFC 1939 定义了这个协议。POP 是一种机制,因特网上大多数人用它得到邮件。它规定每个用户一个邮箱的支持。这就是它所能做的,而这也造成了许多混淆。使用 POP 时,用户熟悉的许多性能并不是由 POP 协议支持的,如查看有几封新邮件消息这一性能。这些性能内建于如 Eudora Microsoft Outlook 之类的程序中,它们能记住一些事,诸如最近一次收到的邮件,还能计算出有多少是新的。所以当使用 JavaMail API 时,如果您想要这类信息,您就必须自己算。

     

           4IMAP

           IMAP 是更高级的用于接收消息的协议。在 RFC 2060 中被定义,IMAP 代表因特网消息访问协议(Internet Message Access Protocol),目前用的是版本 4,也称 IMAP4。在用到 IMAP 时,邮件服务器必需支持这个协议。不能仅仅把使用 POP 的程序用于 IMAP,并指望它支持 IMAP 所有性能。假设邮件服务器支持 IMAP,基于 JavaMail 的程序可以利用这种情况 用户在服务器上有多个文件夹(folder),并且这些文件夹可以被多个用户共享。

           因为有这一更高级的性能,您也许会认为所有用户都会使用 IMAP。事实并不是这样。要求服务器接收新消息,在用户请求时发送到用户手中,还要在每个用户的多个文件夹中维护消息。这样虽然能将消息集中备份,但随着用户长期的邮件夹越来越大,到磁盘空间耗尽时,每个用户都会受到损失。使用 POP,就能卸载邮件服务器上保存的消息了。

          

           5MIME

           MIME 代表多用途因特网邮件扩展标准(Multipurpose Internet Mail Extensions)。它不是邮件传输协议。但对传输内容的消息、附件及其它的内容定义了格式。这里有很多不同的有效文档:RFC 822RFC 2045RFC 2046 RFC 2047。作为一个 JavaMail API 的用户,您通常不必对这些格式操心。无论如何,一定存在这些格式而且程序会用到它。

     

           6NNTP及其他

           因为 JavaMail API 将供应商和所有其它的东西分开了,您就能轻松添加额外的协议支持。Sun 保留了一张第三方供应商列表,他们利用了 Sun 不提供超出(out-of-the-box)支持范围的协议。您会找到 NNTP(网络新闻传输协议)[新闻组]S/MIME(安全多用途因特网邮件扩展)及其它支持。

     

     

          

          

    三、JavaMail的关键对象:

           JavaMail对收发邮件进行了高级的抽象,形成了一些关键的的接口和类,它们构成了程序的基础,下面我们分别来了解一下这些最常见的对象。

    Properties:属性对象

           由于JavaMail需要和邮件服务器进行通信,这就要求程序提供许多诸如服务器地址、端口、用户名、密码等信息,JavaMail通过Properties对象封装这些属性西信息。如下面的代码封装了两个属性信息:

           Properties props = new Properties();

        props.put("mail.smtp.host", "smtp.sina.com.cn");

        props.put("mail.smtp.auth", "true");

       

        针对不同的的邮件协议,JavaMail规定了服务提供者必须支持一系列属性,下表是针对SMTP协议的一些常见属性(属性值都以String类型进行设置,属性类型栏仅表示属性是如何被解析的):

    属性名

    属性类型

    说明

    mail.stmp.host

    String

    SMTP服务器地址,如smtp.sina.com.cn

    mail.stmp.port

    int

    SMTP服务器端口号,默认为25

    mail.stmp.auth

    boolean

    SMTP服务器是否需要用户认证,默认为false

    mail.stmp.user

    String

    SMTP默认的登陆用户名

    mail.stmp.from

    String

    默认的邮件发送源地址

    mail.stmp.socketFactory.class

    String

    socket工厂类类名,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.net.SocketFactory接口

    mail.stmp.socketFactory.port

    int

    指定socket工厂类所用的端口号,如果没有规定,则使用默认的端口号

    mail.smtp.socketFactory.fallback

    boolean

    设置为true时,当使用指定的socket类创建socket失败后,将使用java.net.Socket创建socket,默认为true

    mail.stmp.timeout

    int

    I/O连接超时时间,单位为毫秒,默认为永不超时

           其他几个协议也有类似的一系列属性,如POP3mail.pop3.hostmail.pop3.port以及IMAPmail.imap.hostmail.imap.port等。更详细的信息请查看com.sun.mail.smtpcom.sun.mail.pop3com.sun.mail.imap这三个包的Javadochttp://java.sun.com/products/javamail/javadocs/index.html

     

    Session:会话对象

           Session是一个很容易被误解的类,这归咎于混淆视听的类名。千万不要以为这里的SessionHttpSession一样代表真实的交互会话,但创建Session对象时,并没有对应的物理连接,它只不过是一对配置信息的集合。Session的主要作用包括两个方面:

           1)接收各种配置属性信息:通过Properties对象设置的属性信息;

           2)初始化JavaMail环境:根据JavaMail的配置文件,初始化JavaMail环境,以便通过Session对象创建其他重要类的实例。

           所以,如果把Session更名为Configure也许更容易理解一些。JavaMail提供者在Jar包的META-INF目录下,通过以下文件提供了基本配置信息,以便session能够根据这个配置文件加载提供者的实现类:

    l         javamail.providersjavamail.default.providers

    l         javamail.address.mapjavamail.default.address.map

           下面是Sun提供者java.mail.default.providers文件的配置信息(位于mail.jar中):

        # JavaMail IMAP provider Sun Microsystems, Inc

        protocol=imap; type=store; class=com.sun.mail.imap.IMAPStore; vendor=Sun Microsystems, Inc;

        protocol=imaps; type=store; class=com.sun.mail.imap.IMAPSSLStore; vendor=Sun Microsystems, Inc;

        # JavaMail SMTP provider Sun Microsystems, Inc

        protocol=smtp; type=transport; class=com.sun.mail.smtp.SMTPTransport; vendor=Sun Microsystems, Inc;

        protocol=smtps; type=transport;    class=com.sun.mail.smtp.SMTPSSLTransport; vendor=Sun Microsystems, Inc;

        # JavaMail POP3 provider Sun Microsystems, Inc

        protocol=pop3; type=store; class=com.sun.mail.pop3.POP3Store; vendor=Sun Microsystems, Inc;

        protocol=pop3s; type=store; class=com.sun.mail.pop3.POP3SSLStore; vendor=Sun Microsystems, Inc;

           这个配置文件提供了以下四个方面的信息:

           protocol:协议名称;

           type:协议类型;

           class:对应该操作类型的实现类;

           vendor:厂商名称。

           Session在加载配置文件时会按照以下优先级顺序进行:

           1)首先使用<JAVA_HOME>/lib中的javamail.providers

           2)如果1)不存在相应的配置文件,使用类路径下mail.jarMETA-INF目录下的javamail.providers

           3)如果2)不存在相应的配置文件,使用类路径下的mail.jarMETA-INF目录下的javamail.default.providers

           所以开发者可以在<JAVA_HOME>/lib目录下提供配置文件覆盖mail.jar/META-INF目录中厂商的配置。但是,一般情况下,我们无须这样做。

           Session通过JavaMail配置文件以及程序中设置的Properties对象构建一个邮件处理环境,后续的处理将在Session基础上进行。Session拥有多个静态工厂方法用于创建Session实例。

    l         static Session getDefaultInstance(Properties props, Authenticator authenticator):当JVM中已经存在默认的Session实例中,直接返回这个实例,否则创建一个新的Session实例,并将其作为JVM中默认Session实例。这个API很诡异,我们将对它进行详细的讲解。由于这个默认Session实例可以被同一个JVM所有的代码访问到,而Session中本身又可能包括密码、用户名等敏感信息在内的所有属性信息,所以后续调用也必须传入和第一次相同的Authenticator实例,否则将抛出java.lang.SecurityException异常。如果第一次调用时Authenticator入参为null,则后续调用通过nullAuthenticator入参或直接使用getDefaultInstance(Properties props)即可返回这个默认的Session实例。值得一提的是,虽然后续调用也会传入Properties,但新属性并不会起作用,如果希望采用新的属性值,则可以通过getDefaultInstance(Properties props)创建一个新的Session实例达到目的。Authenticator在这里承当了两个功能:首先,对JVM中默认Session实例进行认证保护,后续调用执行getDefaultInstance(Properties props, Authenticator authenticator)方法时必须和第一次一样;其次,在具体和邮件服务器交互时,又作为认证的信息;

    l         static Session getDefaultInstance(Properties props):返回JVM中默认的Session实例,如果第一次创建Session未指定Authenticator入参,后续调用可以使用该访问获取Session;

    l         static Session getInstance(Properties props, Authenticator authenticator):创建一个新的Session实例,它不会在JVM中被作为默认实例共享;

    l         static Session getInstance(Properties props):根据相关属性创建一个新的Session实例,未使用安全认证信息;

           SessionJavaMail提供者配置文件以及设置属性信息的“容器”,Session本身不会和邮件服务器进行任何的通信。所以在一般情况下,我们仅需要通过getDefaultInstance()获取一个共享的Session实例就可以了,下面的代码创建了一个Session实例:

           Properties props = System.getProperties();

        props.setProperty("mail.transport.protocol", "smtp");             

        Session session = Session.getDefaultInstance(props);

     

    TransportStore:传输和存储

           邮件操作只有发送或接收两种处理方式,JavaMail将这两种不同操作描述为传输(javax.mail.Transport)和存储(javax.mail.Store),传输对应邮件的发送,而存储对应邮件的接收。

           Session提供了几个用于创建TransportStore实例的方法,在具体讲解这些方法之前,我们事先了解一下Session创建TransportStore的内部机制。我们知道提供者在javamail.providers配置文件中为每一种支持的邮件协议定义了实现类,Session根据协议类型(stmppop3等)和邮件操作方式(传输和存储)这两个信息就可以定位到一个实例类上。比如,指定stmp协议和transport类型后,Session就会使用com.sun.mail.smtp.SMTPTransport实现类创建一个Transport实例,而指定pop3协议和store类型时,则会使用com.sun.mail.pop3.POP3Store实例类创建一个Store实例。Session提供了多个重载的getTransport()getStore()方法,这些方法将根据SessionProperties属性设置情况进行工作,影响这两套方法工作的属性包括:

    属性名

    说明

    mail.transport.protocol

    默认的邮件传输协议,例如,smtp

    mail.store.protocol

    默认的存储邮件协议,例如:pop3

    mail.host

    默认的邮件服务地址,例如:192.168.67.1

    mail.user

    默认的登陆用户名,例如:zapldy

    下面,我们再回头来了解SessiongetTransport()getStore()的重载方法。

    l         Transport getTransport():当Session实例设置了mail.transport.protocol属性时,该方法返回对应的Transport实例,否则抛出javax.mail.NoSuchProviderException

    l         Transport getTransport(String protocol):如果Session没有设置mail.transport.protocol属性,可以通过该方法返回指定类型的Transport,如transport = session.getTransport(“smtp”)

    如果Session中未包含Authenticator,以上两方法创建的Transport实例和邮件服务器交互时必须显示提供用户名/密码的认证信息。如果Authenticator非空,则可以在和邮件服务器交互时被作为认证信息使用。除了以上两种提供认证信息的方式外,Session还可以使用以下的方法为Transport提供认证信息。

    Transport getTransport(URLName url):用户可以通过URLName入参指定邮件协议、邮件服务器、端口、用户名和密码信息,请看下面的代码:

           URLName urln = new URLName(“smtp”, “smtp.sina.com.cn”, 25, null, “masterspring2”, “spring”);

           Transport transport = session.getTransport(urln);

           这里,指定了邮件协议为smtp,邮件服务器是smtp.sina.com.cn,端口为25,用户名/密码为masterspring2/spring

          

           消息发送的最后一部分是使用  Transport 类。这个类用协议指定的语言发送消息(通常是 SMTP)。它是抽象类,它的工作方式与 Session 有些类似。仅调用静态 send() 方法,就能使用类的 缺省 版本:

    Transport.send(message);

    或者,您也可以从针对您的协议的会话中获得一个特定的实例,传递用户名和密码(如果不必要就不传),发送消息,然后关闭连接。

    message.saveChanges(); // implicit with send()

    Transport transport = session.getTransport("smtp");

    transport.connect(host, username, password);

    transport.sendMessage(message, message.getAllRecipients());

    transport.close();

    后面这种方法在您要发送多条消息时最好,因为它能保持邮件服务器在消息间的活动状态。基本 send() 机制为每个方法的调用设置与服务器独立的连接。

           注意:要观察传到邮件服务器上的邮件命令,请用 session.setDebug(true) 设置调试标志。

     

           Session 获取消息与发送消息开始很相似。但是,在 session 得到后,很可能使用用户名和密码或使用 Authenticator 连接到一个 Store。类似于 Transport ,您告知 Store 使用什么协议:

    // Store store = session.getStore("imap");

    Store store = session.getStore("pop3");

    store.connect(host, username, password);

     

    连接到 Store 之后,接下来,您就可以获取一个 Folder,您必需先打开它,然后才能读里面的消息。

    Folder folder = store.getFolder("INBOX");

    folder.open(Folder.READ_ONLY);

    Message message[] = folder.getMessages();

    POP3 唯一可以用的文件夹是 INBOX。如果使用 IMAP,还可以用其它文件夹。

    注意:Sun 的供应商有意变得聪明。虽然 Message message[] = folder.getMessages(); 看上去是个很慢的操作,它从服务器上读取每一条消息,但仅在你实际需要消息的一部分时,消息的内容才会被检索。

    一旦有了要读的 Message,您可以用 getContent() 来获取其内容,或者用 writeTo() 将内容写入流。getContent() 方法只能得到消息内容,而 writeTo() 的输出却包含消息头。

    System.out.println(((MimeMessage)message).getContent());

    一旦读完邮件,要关闭与 folder store 的连接。

    folder.close(aBoolean);

    store.close();

    传递给 folder close() 方法的 boolean 表示是否清除已删除的消息从而更新 folder

          

    Message:消息对象

           一旦获得 Session 对象,就可以继续创建要发送的消息。这由 Message 类来完成。因为 Message 是个抽象类,您必需用一个子类,多数情况下为 javax.mail.internet.MimeMessageMimeMessage 是个能理解 MIME 类型和头的电子邮件消息,正如不同 RFC 中所定义的。虽然在某些头部域非 ASCII 字符也能被译码,但 Message 头只能被限制为用 US-ASCII 字符。

     

    要创建一个 Message,请将 Session 对象传递给 MimeMessage 构造器:

     

    MimeMessage message = new MimeMessage(session);

     

    注意:还存在其它构造器,如用按 RFC822 格式的输入流来创建消息。

     

    一旦获得消息,您就可以设置各个部分,因为 Message 实现 Part 接口(且 MimeMessage 实现 MimePart )。设置内容的基本机制是 setContent() 方法,同时使用参数,分别代表内容和 mime 类型:

     

    message.setContent("Hello", "text/plain");

     

    但如果,您知道您在使用 MimeMessage,而且消息是纯文本格式,您就可以用 setText() 方法,它只需要代表实际内容的参数,( MIME 类型缺省为 text/plain):

     

    message.setText("Hello");

     

    后一种格式是设置纯文本消息内容的首选机制。至于发送其它类型的消息,如 HTML 文件格式的消息,我们首选前者。

     

    setSubject() 方法设置 subject(主题):

     

    message.setSubject("First");

     

    下面的代码演示了创建一个简单邮件信息的过程:

    Message msg = new MimeMessage(session);

    msg.setSubject("Test Title");

    msg.setText("How are you!");

    msg.setSentDate(new Date());

     

     

    Address:地址

           一旦您创建了 Session Message,并将内容填入消息后,就可以用 Address 确定信件地址了。和 Message 一样,Address 也是个抽象类。您用的是 javax.mail.internet.InternetAddress 类。

     

    若创建的地址只包含电子邮件地址,只要传递电子邮件地址到构造器就行了。

     

    Address address = new InternetAddress("president@whitehouse.gov");

     

    若希望名字紧挨着电子邮件显示,也可以把它传递给构造器:

     

    Address address = new InternetAddress("president@whitehouse.gov", "George Bush");

     

    需要为消息的 from 域和 to 域创建地址对象。除非邮件服务器阻止,没什么能阻止你发送一段看上去是来自任何人的消息。

     

    一旦创建了 address(地址),将它们与消息连接的方法有两种。如果要识别发件人,您可以用 setFrom() setReplyTo() 方法。

     

    message.setFrom(address)

     

    需要消息显示多个 from 地址,可以使用 addFrom() 方法:

     

    Address address[] = ...;

    message.addFrom(address);

     

    若要识别消息 recipient(收件人),您可以使用 addRecipient() 方法。除 address(地址)外,这一方法还请求一个 Message.RecipientType

     

    message.addRecipient(type, address)

     

    三种预定义的地址类型是:

     

    Message.RecipientType.TO

    Message.RecipientType.CC

    Message.RecipientType.BCC

    如果消息是发给副总统的,同时发送一个副本(carbon copy)给总统夫人,以下做法比较恰当:

     

    Address toAddress = new InternetAddress("vice.president@whitehouse.gov");

    Address ccAddress = new InternetAddress("first.lady@whitehouse.gov");

    message.addRecipient(Message.RecipientType.TO, toAddress);

    message.addRecipient(Message.RecipientType.CC, ccAddress);

     

     

    JavaMail API 没有提供电子邮件地址有效性核查机制。虽然通过编程,自己能够扫描有效字符(如 RFC 822 中定义的)或验证邮件交换(mail exchangeMX)记录,但这些功能不属于 JavaMail API

     

    Authenticator:认证者

           java.net 类一样,JavaMail API 也可以利用 Authenticator 通过用户名和密码访问受保护的资源。对于JavaMail API 来说,这些资源就是邮件服务器。JavaMail Authenticator javax.mail 包中,而且它和 java.net 中同名的类 Authenticator 不同。两者并不共享同一个 Authenticator,因为JavaMail API 用于 Java 1.1,它没有 java.net 类别。

     

           要使用 Authenticator,先创建一个抽象类的子类,并从 getPasswordAuthentication() 方法中返回 PasswordAuthentication 实例。创建完成后,您必需向 session 注册 Authenticator。然后,在需要认证的时候,就会通知 Authenticator。您可以弹出窗口,也可以从配置文件中(虽然没有加密是不安全的)读取用户名和密码,将它们作为 PasswordAuthentication 对象返回给调用程序。

     

    Properties props = new Properties();

    // fill props with any information

    Authenticator auth = new MyAuthenticator();

    Session session = Session.getDefaultInstance(props, auth);

     

    发送消息:

           发送电子邮件消息这一过程包括获取一个会话,创建并填充一则消息,然后发送。得到 Session 时,经由设置传递的 Properties 对象中的 mail.smtp.host 属性,可以指定您的 SMTP 服务器:

     

    String host = ...;

    String from = ...;

    String to = ...;

     

    // Get system properties

    Properties props = System.getProperties();

     

    // Setup mail server

    props.put("mail.smtp.host", host);

     

    // Get session

    Session session = Session.getDefaultInstance(props, null);

     

    // Define message

    MimeMessage 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");

     

      // Send message

      Transport.send(message);

     

    您应该将代码放在一个 try-catch 程序块中,这样创建和发送消息时就能够抛出异常。

     

    消息的提取:

           为读邮件,您获取一个会话,获取并连接一个用于邮箱的适宜的存储(store),打开适宜的文件夹,然后获取您的消息。同样,切记完成后关闭连接。

     

      String host = ...;

      String username = ...;

      String password = ...;

     

      // Create empty properties

      Properties props = new Properties();

     

      // Get session

      Session session = Session.getDefaultInstance(props, null);

     

      // Get the store

      Store store = session.getStore("pop3");

      store.connect(host, username, password);

     

      // Get folder

      Folder folder = store.getFolder("INBOX");

      folder.open(Folder.READ_ONLY);

     

      // Get directory

      Message message[] = folder.getMessages();

     

      for (int i=0, n=message.length; i<n; i++) {

         System.out.println(i + ": " + message[i].getFrom()[0]

              + "/t" + message[i].getSubject());

              }

     

              // Close connection

              folder.close(false);

              store.close();

     

    对每条消息做些什么由您决定。上面的代码块只是显示这些消息的发件人和主题。技术上讲,from 地址列表可能为空,而 getFrom()[0] 调用会抛出一个异常。

     

    要显示全部信息,您可以在用户看完 from subject 域之后给出提示,如用户有需要,就调用消息的 writeTo() 方法来实现。

     

              BufferedReader reader = new BufferedReader (

                new InputStreamReader(System.in));

     

              // Get directory

              Message message[] = folder.getMessages();

              for (int i=0, n=message.length; i<n; i++) {

                System.out.println(i + ": " + message[i].getFrom()[0]

                  + "/t" + message[i].getSubject());

     

                System.out.println("Do you want to read message? " +

                  "[YES to read/QUIT to end]");

                String line = reader.readLine();

                if ("YES".equals(line)) {

                  message[i].writeTo(System.out);

                } else if ("QUIT".equals(line)) {

                  break;

                }

              }

     

     

    消息和标识的删除:

           消息的删除涉及使用与消息相关的 Flags(标志)。不同 flag 对应不同的状态,有些由系统定义而有些则由用户定义。下面列出在内部类 Flags.Flag 中预定义的标志:

     

        * Flags.Flag.ANSWERED

        * Flags.Flag.DELETED

        * Flags.Flag.DRAFT

        * Flags.Flag.FLAGGED

        * Flags.Flag.RECENT

        * Flags.Flag.SEEN

        * Flags.Flag.USER

     

    仅仅因为存在一个标志,并不意味着所有邮件服务器或供应商都支持这个标志。例如,除了删除消息标志外,POP 协议不再支持其它任何标志。检查是否存在新邮件,这不是个 POP 任务,而是内建于邮件客户机的任务。为找出哪些标志能被支持,可以用 getPermanentFlags() folder 提出要求。

     

    要删除消息,您可以设置消息的 DELETED flag

     

    message.setFlag(Flags.Flag.DELETED, true);

     

    首先,请以 READ_WRITE 模式打开 folder

     

    folder.open(Folder.READ_WRITE);

     

    然后,当所有消息的处理完成后,关闭 folder,并传递一个 true 值,从而擦除(expunge)有 delete 标志的消息。

     

    folder.close(true);

     

    一个 Folder expunge() 方法可以用来删除消息。但 Sun POP3 供应商不支持。其它供应商有的或许能够实现这一功能,而有的则不能。IMAP 供应商极有可能实现此功能。因为 POP 只支持单个对邮箱的访问,对 Sun 的供应商来说,您必需关闭 folder 以删除消息。

     

    要取消标志,只要传递 false setFlag() 方法就行了。想知道是否设置过标志,可以用 isSet() 检查。

     

    亲自认证:

           您已经知道 如果需要可以用一个 Authenticator 提示用户输入用户名和密码,而不是将用户名和密码作为字符串传递。在这里您会明确了解怎样更充分的使用认证。

     

    不用主机、用户名和密码与 Store 相连接,而是设置 Properties 来拥有主机,然后告诉 Session 自定义的 Authenticator 实例,如下所示:

     

     

    // Setup properties

    Properties props = System.getProperties();

    props.put("mail.pop3.host", host);

     

    // Setup authentication, get session

    Authenticator auth = new PopupAuthenticator();

    Session session = Session.getDefaultInstance(props, auth);

     

    // Get the store

    Store store = session.getStore("pop3");

    store.connect();

     

    然后,您创建一个 Authenticator 子类并从 getPasswordAuthentication() 方法中返回 PasswordAuthentication 对象。下面就是这样一种实现,其中用户名和密码仅占用一个域。(这不是一个 Swing 工程教程;只要将两部分输入同一个域,用逗号分隔就行。)

     

    import javax.mail.*;

    import javax.swing.*;

    import java.util.*;

     

    public class PopupAuthenticator extends Authenticator {

     

      public PasswordAuthentication getPasswordAuthentication() {

        String username, password;

     

        String result = JOptionPane.showInputDialog(

          "Enter 'username,password'");

     

        StringTokenizer st = new StringTokenizer(result, ",");

        username = st.nextToken();

        password = st.nextToken();

     

        return new PasswordAuthentication(username, password);

      }

     

    }

     

    因为 PopupAuthenticator 涉及到 Swing,它会启动 AWT 的事件处理线程。这一点基本上要求您在代码中添加一个对 System.exit() 的调用来终止程序。

     

    消息的回复:

           Message 类引入一个 reply() 方法来配置一个新 Message,包括正确的 recipient(收件人)和添加“Re”(如果没有就添加)的正确的 subject。这样做并没有为消息添加新内容,仅仅将 from reply-to(被回复人) 头复制给新的收件人。这种方法用一个 boolean 参数指定消息只回复给发件人(false)或回复给全体(true)。

     

     

    MimeMessage reply = (MimeMessage)message.reply(false);

    reply.setFrom(new InternetAddress("president@whitehouse.gov"));

    reply.setText("Thanks");

    Transport.send(reply);

     

    在发送消息时要配置 reply to(被回复人) 地址,可以用 setReplyTo() 方法。

     

    消息的转发:

    转发消息有一点棘手。没有单独的方法可以调用,您通过对组成消息各部分的处理来组织要转发的消息。

     

    一条邮件消息可以由多个部分组成。在处理 MIME 消息时,消息中每部分都是 BodyPart,再特殊些,是 MimeBodyPart。不同的 body part(信体部件或正文部件)结合成一个容器,名为 Multipart,再特殊些,就是 MimeMultipart。要转发一条消息,您为自己的消息正文创建一个部件,要转发的消息作为另一部件。并且将两个部件结合成一个 multipart(多部件)。然后您将这个 multipart 添加到一则已写好恰当地址的消息中,并发送。

     

    本质上就是如此。要将一条消息内容复制到另一条,只要复制 DataHandler JavaBeans Activation Framework 中的类)就行了。

     

     

    // Create the message to forward

    Message forward = new MimeMessage(session);

     

    // Fill in header

    forward.setSubject("Fwd: " + message.getSubject());

    forward.setFrom(new InternetAddress(from));

    forward.addRecipient(Message.RecipientType.TO,

      new InternetAddress(to));

     

    // Create your new message part

    BodyPart messageBodyPart = new MimeBodyPart();

    messageBodyPart.setText(

      "Here you go with the original message:/n/n");

     

    // Create a multi-part to combine the parts

    Multipart multipart = new MimeMultipart();

    multipart.addBodyPart(messageBodyPart);

     

    // Create and fill part for the forwarded content

    messageBodyPart = new MimeBodyPart();

    messageBodyPart.setDataHandler(message.getDataHandler());

     

    // Add part to multi part

    multipart.addBodyPart(messageBodyPart);

     

    // Associate multi-part with message

    forward.setContent(multipart);

     

    // Send message

    Transport.send(forward);

     

     

    附件的处理:

    附件是邮件消息的相关资源,如通常不包含在消息正文里文本文件、电子表格或图像等。常见的邮件程序,如 Eudora pine 之类,可以用 JavaMail API 将资源 attach(附加) 到您的消息上,就可以在收到消息时得到。

     

    附件的发送:

    发送附件非常像转发消息。您建立各部分以组成完整消息。完成第一部件,即消息正文后,您添加其它部件,其中每个 DataHandler 都代表附件,而不是转发消息情况下的共享处理程序。如果从文件中读附件,附件的数据源是 FileDataSource。而如果从 URL 中读时,附件的数据源是 URLDataSource。一旦存在 DataSource,只要先把它传递给 DataHandler 构造器,最后再用 setDataHandler() 把它附加到 BodyPart。假定您要保留附件的原始文件名,最终要做的是用 BodyPart setFileName() 方法设置与附件相关的文件名。如下所示:

     

     

      // Define message

      Message message = new MimeMessage(session);

      message.setFrom(new InternetAddress(from));

      message.addRecipient(Message.RecipientType.TO,

        new InternetAddress(to));

      message.setSubject("Hello JavaMail Attachment");

     

      // Create the message part

      BodyPart messageBodyPart = new MimeBodyPart();

     

      // Fill the message

      messageBodyPart.setText("Pardon Ideas");

     

      Multipart multipart = new MimeMultipart();

      multipart.addBodyPart(messageBodyPart);

     

      // Part two is attachment

      messageBodyPart = new MimeBodyPart();

      DataSource source = new FileDataSource(filename);

      messageBodyPart.setDataHandler(new DataHandler(source));

      messageBodyPart.setFileName(filename);

      multipart.addBodyPart(messageBodyPart);

     

      // Put parts in message

      message.setContent(multipart);

     

      // Send the message

      Transport.send(message);

     

     

    就消息引入附件时,若程序是个 servlet (小服务程序),除告知消息发送到何处外,还必需上载附件。可以将 multipart/form-data 表单编码类型(form encoding type)用于每个上载文件的处理。

     

     

    <FORM ENCTYPE="multipart/form-data"

        method=post action="/myservlet">

      <INPUT TYPE="file" NAME="thefile">

      <INPUT TYPE="submit" VALUE="Upload">

    </FORM>

     

    注意:消息大小由 SMTP 服务器而不是 JavaMail API 来限制。如果您碰到问题,可以考虑用设置 ms mx 参数的方法增大 Java 堆大小。

     

    附件的获取:

    从消息中获取附件比发送它们棘手些,因为 MIME 没有简单的关于附件的概念。当消息包含附件时,消息的内容是个 Multipart 对象。接着,您需要处理每个 Part,获取主要内容和附件。标有从 part.getDisposition() 获得的 Part.ATTACHMENT 配置(disposition)的部件(Part)无疑就是附件。但是,没有配置(以及一个非文本 MIME 类型)和带 Part.INLINE 配置的部件也可能是附件。当配置要么是 Part.ATTACHMENT,要么是 Part.INLINE 时,这个消息部件的内容就能被保存。只要用 getFileName() getInputStream() 就能分别得到原始文件名和输入流。

     

    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());

      }

    }

     

    saveFile() 方法仅依据文件名创建了一个 File,它从输入流中将字节读出,然后写入到文件中。万一文件已经存在,就在文件名后添加一个数字作为新文件名,如果这个文件名仍存在,则继续添,直到找不到这样的文件名为止。

     

    // from saveFile()

    File file = new File(filename);

    for (int i=0; file.exists(); i++) {

      file = new File(filename+i);

    }

     

    上面的代码涵盖了最简单的情况 消息中各部件恰当的标记了。要涵盖所有情况,还要在配置为空时进行处理,并且获取部件的 MIME 类型来进行相应处理。

     

    if (disposition == null) {

      // Check if plain

      MimeBodyPart mbp = (MimeBodyPart)part;

      if (mbp.isMimeType("text/plain")) {

         // Handle plain

      } else {

         // Special non-attachment cases here of image/gif, text/html, ...

      }

      ...

    }

     

    HTML 消息的处理

    发送基于 HTML 文件格式消息的工作量比发送纯文本消息多,虽然不一定非要这些多余的工作量。如何选择完全取决于给定的请求。

     

    HTML 消息的发送:

    若您所要做的全部事情是发送一份 HTML 文件的等价物作为消息,但让邮件阅读者为不能提取任何内嵌图像或相关片段而担心的话,可以使用 Message setContent() 方法,把内容当作一个 String 传入,并将内容类型设置成 text/html

     

     

    String htmlText = "<H1>Hello</H1>" +

      "<img src=/"http://www.jguru.com/images/logo.gif/">";

    message.setContent(htmlText, "text/html"));

     

    在接收端,如果您用 JavaMail API 提取消息,API 中没有内建的显示 HTML 消息的东西。 JavaMail API 只把它看成一串字节流。要显示 HTML 文件格式的消息,您必需使用 Swing JEditorPane 或其它第三方 HTML 格式查看器组件。

     

     

    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();

    }

     

    在消息中引入图像:

    另一方面,如果您想让 HTML 文件格式内容的消息完整(内嵌的图像作为消息的一部分),您必需把图像作为附件,并且用一个给定的 cid URL 引用图像,其中 cid 是图像附件 Content-ID 头的引用。

     

    嵌入图像的过程与附加文件到消息的过程非常相似,唯一的区别在于您必需通过设置 MimeMultipart 构造器中的子类型(或者说用 setSubType())告知 MimeMultipart 各个相关部件,并且将这个图像的 Content-ID 头设置成随机字符串,作为图像的 src img 标记中使用。完整的演示如下。

     

    String file = ...;

     

    // Create the message

    Message message = new MimeMessage(session);

     

    // Fill its headers

    message.setSubject("Embedded Image");

    message.setFrom(new InternetAddress(from));

    message.addRecipient(Message.RecipientType.TO,

      new InternetAddress(to));

     

    // Create your new message part

    BodyPart messageBodyPart = new MimeBodyPart();

    String htmlText = "<H1>Hello</H1>" +

      "<img src=/"cid:memememe/">";

    messageBodyPart.setContent(htmlText, "text/html");

     

    // Create a related multi-part to combine the parts

    MimeMultipart multipart = new MimeMultipart("related");

    multipart.addBodyPart(messageBodyPart);

     

    // Create part for the image

    messageBodyPart = new MimeBodyPart();

     

    // Fetch the image and associate to part

    DataSource fds = new FileDataSource(file);

    messageBodyPart.setDataHandler(new DataHandler(fds));

    messageBodyPart.setHeader("Content-ID","memememe");

     

    // Add part to multi-part

    multipart.addBodyPart(messageBodyPart);

     

    // Associate multi-part with message

    message.setContent(multipart);

    展开全文
  • JavaWeb-JavaMail邮件开发

    万次阅读 2018-07-13 11:27:22
    Email的历史比Web还要久远,直到现在,Email也是互联网上应用非常广泛的服务。 几乎所有的编程语言都支持发送和接收电子邮件,但是,先等等,在我们开始编写代码之前,有必要搞清楚电子邮件是如何在互联网上...

     

    javamail

    Email的历史比Web还要久远,直到现在,Email也是互联网上应用非常广泛的服务。

    几乎所有的编程语言都支持发送和接收电子邮件,但是,先等等,在我们开始编写代码之前,有必要搞清楚电子邮件是如何在互联网上运作的。

    我们来看看传统邮件是如何运作的。假设你现在在北京,要给一个香港的朋友发一封信,怎么做呢?

    首先你得写好信,装进信封,写上地址,贴上邮票,然后就近找个邮局,把信仍进去。

    信件会从就近的小邮局转运到大邮局,再从大邮局往别的城市发,比如先发到天津,再走海运到达香港,也可能走京九线到香港,但是你不用关心具体路线,你只需要知道一件事,就是信件走得很慢,至少要几天时间。

    信件到达香港的某个邮局,也不会直接送到朋友的家里,因为邮局的叔叔是很聪明的,他怕你的朋友不在家,一趟一趟地白跑,所以,信件会投递到你的朋友的邮箱里,邮箱可能在公寓的一层,或者家门口,直到你的朋友回家的时候检查邮箱,发现信件后,就可以取到邮件了。

    电子邮件的流程基本上也是按上面的方式运作的,只不过速度不是按天算,而是按秒算。

    现在我们回到电子邮件,假设我们自己的电子邮件地址是me@163.com,对方的电子邮件地址是friend@sina.com(注意地址都是虚构的哈),现在我们用Outlook或者Foxmail之类的软件写好邮件,填上对方的Email地址,点“发送”,电子邮件就发出去了。这些电子邮件软件被称为MUA:Mail User Agent——邮件用户代理。

    Email从MUA发出去,不是直接到达对方电脑,而是发到MTA:Mail Transfer Agent——邮件传输代理,就是那些Email服务提供商,比如网易、新浪等等。由于我们自己的电子邮件是163.com,所以,Email首先被投递到网易提供的MTA,再由网易的MTA发到对方服务商,也就是新浪的MTA。这个过程中间可能还会经过别的MTA,但是我们不关心具体路线,我们只关心速度。

    Email到达新浪的MTA后,由于对方使用的是@sina.com的邮箱,因此,新浪的MTA会把Email投递到邮件的最终目的地MDA:Mail Delivery Agent——邮件投递代理。Email到达MDA后,就静静地躺在新浪的某个服务器上,存放在某个文件或特殊的数据库里,我们将这个长期保存邮件的地方称之为电子邮箱。

    同普通邮件类似,Email不会直接到达对方的电脑,因为对方电脑不一定开机,开机也不一定联网。对方要取到邮件,必须通过MUA从MDA上把邮件取到自己的电脑上。

    所以,一封电子邮件的旅程就是:

    发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- 收件人

    email

    有了上述基本概念,要编写程序来发送和接收邮件,本质上就是:

    1. 编写MUA把邮件发到MTA;
    2. 编写MUA从MDA上收邮件。

    发邮件时,MUA和MTA使用的协议就是SMTP:Simple Mail Transfer Protocol,后面的MTA到另一个MTA也是用SMTP协议。

    收邮件时,MUA和MDA使用的协议有两种:POP:Post Office Protocol,目前版本是3,俗称POP3;IMAP:Internet Message Access Protocol,目前版本是4,优点是不但能取邮件,还可以直接操作MDA上存储的邮件,比如从收件箱移到垃圾箱,等等。

    邮件客户端软件在发邮件时,会让你先配置SMTP服务器,也就是你要发到哪个MTA上。假设你正在使用163的邮箱,你就不能直接发到新浪的MTA上,因为它只服务新浪的用户,所以,你得填163提供的SMTP服务器地址:smtp.163.com,为了证明你是163的用户,SMTP服务器还要求你填写邮箱地址和邮箱口令,这样,MUA才能正常地把Email通过SMTP协议发送到MTA。

    类似的,从MDA收邮件时,MDA服务器也要求验证你的邮箱口令,确保不会有人冒充你收取你的邮件,所以,Outlook之类的邮件客户端会要求你填写POP3或IMAP服务器地址、邮箱地址和口令,这样,MUA才能顺利地通过POP或IMAP协议从MDA取到邮件。

    在收发邮件前,请先准备好至少两个电子邮件,如xxx@163.com,xxx@sina.com,xxx@qq.com等,注意两个邮箱不要用同一家邮件服务商。

    1. 邮件协议

    1.1 收发邮件

    发邮件大家都会吧!发邮件是从客户端把邮件发送到邮件服务器,收邮件是把邮件服务器的邮件下载到客户端。

    javamail

    我们在163、126、QQ、sohu、sina等网站注册的Email账户,其实就是在邮件服务器中注册的。这些网站都有自己的邮件服务器。

    1.2 邮件协议概述

    与HTTP协议相同,收发邮件也是需要有传输协议的。

    • SMTP:(Simple Mail Transfer Protocol,简单邮件传输协议)发邮件协议;
    • POP3:(Post Office Protocol Version 3,邮局协议第3版)收邮件协议;
    • IMAP:(Internet Message Access Protocol,因特网消息访问协议)收发邮件协议,我们的课程不涉及该协议。

    1.3 理解邮件收发过程

    其实你可以把邮件服务器理解为邮局!如果你需要给朋友寄一封信,那么你需要把信放到邮筒中,这样你的信会“自动”到达邮局,邮局会把信邮到另一个省市的邮局中。然后这封信会被送到收信人的邮箱中。最终收信人需要自己经常查看邮箱是否有新的信件。

    其实每个邮件服务器都由SMTP服务器和POP3服务器构成,其中SMTP服务器负责发邮件的请求,而POP3负责收邮件的请求。

    javamail

    当然,有时我们也会使用163的账号,向126的账号发送邮件。这时邮件是发送到126的邮件服务器,而对于163的邮件服务器是不会存储这封邮件的。

    javamail

    1.4 邮件服务器名称

    smtp服务器的端口号为25,服务器名称为smtp.xxx.xxx。 
    pop3服务器的端口号为110,服务器名称为pop3.xxx.xxx。

    例如:

    • 163:smtp.163.com和pop3.163.com;
    • 126:smtp.126.com和pop3.126.com;
    • qq:smtp.qq.com和pop3.qq.com;
    • sohu:smtp.sohu.com和pop3.sohu.com;
    • sina:smtp.sina.com和pop3.sina.com。

    2. Telnet收发邮件

    Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。要开始一个telnet会话,必须输入用户名和密码来登录服务器。Telnet是常用的远程控制Web服务器的方法

    2.1 BASE64加密

    BASE64是一种加密算法,这种加密方式是可逆的!它的作用是使加密后的文本无法用肉眼识别。Java提供了sun.misc.BASE64Encoder这个类,用来对做Base64的加密和解密,但我们知道,使用sun包下的东西会有警告!甚至在eclipse中根本使用不了这个类(需要设置),所以我们还是听sun公司的话,不要去使用它内部使用的类,我们去使用apache commons组件中的codec包下的Base64这个类来完成BASE64加密和解密。

    package cn.itcast;
    import org.apache.commons.codec.binary.Base64;
    
    public class Base64Utils {
        public static String encode(String s) {
            return encode(s, "utf-8");
        }
    
        public static String decode(String s) {
            return decode(s, "utf-8");
        }
    
        public static String encode(String s, String charset) {
            try {
                byte[] bytes = s.getBytes(charset);
                bytes = Base64.encodeBase64(bytes);
                return new String(bytes, charset);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public static String decode(String s, String charset) {
            try {
                byte[] bytes = s.getBytes(charset);
                bytes = Base64.decodeBase64(bytes);
                return new String(bytes, charset);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    2.2 telnet发邮件

    Xshell是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特色帮助用户在复杂的网络环境中享受他们的工作

    Xshell可以在Windows界面下用来访问远端不同系统下的服务器,从而比较好的达到远程控制终端的目的。

    连接163的smtp服务器

    javamail

    连接成功后需要如下步骤才能发送邮件:

    (1)、与服务器打招呼:ehlo你的名字

    javamail

    (2)、发出登录请求:auth login

    javamail

    (3)、输入加密后的邮箱名:(itcast_cxf@163.com)aXRjYXN0X2N4ZkAxNjMuY29t

    (4)、输入加密后的邮箱密码:(itcast)aXRjYXN0

    javamail

    (5)、输入谁来发送邮件,即from:mail from:itcast_cxf@163.com

    javamail

    (6)、输入把邮件发给谁,即to:rcpt to:itcast_cxf@126.com

    javamail

    (7)、发送填写数据请求:data

    javamail

    (8)、开始输入数据,数据包含:from、to、subject,以及邮件内容,如果输入结束后,以一个“.”为一行,表示输入结束:

    from:<zhangBoZhi@163.com>
    to:<itcast_cxf@sina.com>
    subject: 我爱上你了
    
    我已经深深的爱上你了,我是张柏芝。
    .

    注意,在标题和邮件正文之间要有一个空行!当要退出时,一定要以一个“.”为单行,表示输入结束。

    (9)、最后一步:quit

    javamail

    3. telnet收邮件

    3.1 telnet收邮件的步骤

    pop3无需使用Base64加密

    收邮件连接的服务器是pop3.xxx.com,pop3协议的默认端口号是110。请注意!这与发邮件完全不同。如果你在163有邮箱账户,那么你想使用telnet收邮件,需要连接的服务器是pop3.163.com

    连接pop3服务器:telnet pop3.163.com 110

    命令 功能描述
    user命令 user 用户名,例如:user itcast_cxf@163.com
    pass命令 pass 密码,例如:pass itcast
    stat命令 stat命令用来查看邮箱中邮件的个数,所有邮件所占的空间
    list命令 list命令用来查看所有邮件,或指定邮件的状态,例如:list 1是查看第一封邮件的大小,
    list是查看邮件列表,即列出所有邮件的编号,及大小
    retr命令 查看指定邮件的内容,例如:retr 1#是查看第一封邮件的内容
    dele命令 标记某邮件为删除,但不是马上删除,而是在退出时才会真正删除
    quit命令 退出!如果在退出之前已经使用dele命令标记了某些邮件,那么会在退出是删除它们


    javamail

    javamail

    javamail

    4. JavaMail

    4.1 JavaMail概述

    Java Mail是由SUN公司提供的专门针对邮件的API,主要Jar包:mail.jar、activation.jar。

    在使用MyEclipse创建web项目时,需要小心!如果只是在web项目中使用java mail是没有什么问题的,发布到Tomcat上运行一点问题都没有! 
    但是如果是在web项目中写测试那就出问题了。

    在MyEclipse中,会自动给web项目导入javax.mail包中的类,但是不全(其实是只有接口,而没有接口的实现类),所以只靠MyEclipse中的类是不能运行java mail项目的,但是如果这时你再去自行导入mail.jar时,就会出现冲突。

    处理方案:到下面路径中找到javaee.jar文件,把javax.mail删除!!!

    D:\Program Files\MyEclipse\Common\plugins\com.genuitec.eclipse.j2eedt.core_10.0.0.me201110301321\data\libraryset\EE_5
    

    4.2 JavaMail中主要类

    java mail中主要类:javax.mail.Session、javax.mail.internet.MimeMessage、javax.mail.Transport。

    Session:表示会话,即客户端与邮件服务器之间的会话!想获得会话需要给出账户和密码,当然还要给出服务器名称。在邮件服务中的Session对象,就相当于连接数据库时的Connection对象。

    MimeMessage:表示邮件类,它是Message的子类。它包含邮件的主题(标题)、内容,收件人地址、发件人地址,还可以设置抄送和暗送,甚至还可以设置附件。

    Transport:用来发送邮件。它是发送器!

    4.3 JavaMail之Hello World

    在使用telnet发邮件时,还需要自己来处理Base64编码的问题,但使用JavaMail就不必理会这些问题了,都由JavaMail来处理。

    第一步:获得Session

    Session session = Session.getInstance(Properties prop, Authenticator auth); 
    

    其中prop需要指定两个键值,一个是指定服务器主机名,另一个是指定是否需要认证!我们当然需要认证!

    Properties prop = new Properties();
    prop.setProperty(“mail.host”, “smtp.163.com”);//设置服务器主机名
    prop.setProperty(“mail.smtp.auth”, “true”);//设置需要认证

    其中Authenticator是一个接口表示认证器,即校验客户端的身份。我们需要自己来实现这个接口,实现这个接口需要使用账户和密码。

    Authenticator auth = new Authenticator() {
        public PasswordAuthentication getPasswordAuthentication () {
            new PasswordAuthentication(“itcast_cxf”, “itcast”);//用户名和密码
        }
    };

    通过上面的准备,现在可以获取得Session对象了:

    Session session = Session.getInstance(prop, auth);
    •  

    第二步:创建MimeMessage对象 
    创建MimeMessage需要使用Session对象来创建:

    MimeMessage msg = new MimeMessage(session);
    •  

    然后需要设置发信人地址、收信人地址、主题,以及邮件正文。

    msg.setFrom(new InternetAddress(“itcast_cxf@163.com”));//设置发信人
    msg.addRecipients(RecipientType.TO, “itcast_cxf@qq.com,itcast_cxf@sina.com”);//设置多个收信人
    msg.addRecipients(RecipientType.CC, “itcast_cxf@sohu.com,itcast_cxf@126.com”);//设置多个抄送
    msg.addRecipients(RecipientType.BCC, ”itcast_cxf@hotmail.com”);//设置暗送
    msg.setSubject(“这是一封测试邮件”);//设置主题(标题)
    msg.setContent(“当然是hello world!”, “text/plain;charset=utf-8”);//设置正文

    第三步:发送邮件

    Transport.send(msg);//发送邮件
    •  

    4.4 JavaMail发送带有附件的邮件

    一封邮件可以包含正文、附件N个,所以正文与N个附件都是邮件的一个部份。

    上面的hello world案例中,只是发送了带有正文的邮件!所以在调用setContent()方法时直接设置了正文,如果想发送带有附件邮件,那么需要设置邮件的内容为MimeMultiPart。

    MimeMulitpart parts = new MimeMulitpart();//多部件对象,可以理解为是部件的集合
    msg.setContent(parts);//设置邮件的内容为多部件内容。

    然后我们需要把正文、N个附件创建为“主体部件”对象(MimeBodyPart),添加到MimeMuiltPart中即可。

    MimeBodyPart part1 = new MimeBodyPart();//创建一个部件
    part1.setCotnent(“这是正文部分”, “text/html;charset=utf-8”);//给部件设置内容
    parts.addBodyPart(part1);//把部件添加到部件集中。
    

    下面我们创建一个附件:

    MimeBodyPart part2 = new MimeBodyPart();//创建一个部件
    part2.attachFile(“F:\\a.jpg”);//设置附件
    part2.setFileName(“hello.jpg”);//设置附件名称
    parts.addBodyPart(part2);//把附件添加到部件集中

    注意,如果在设置文件名称时,文件名称中包含了中文的话,那么需要使用MimeUitlity类来给中文编码:

    part2.setFileName(MimeUitlity.encodeText(“美女.jpg”));
    •  

    JavaMail

    public class JavaMailDemo {
    
      public void sendMail() throws Exception {
        /*
         * 1. 得到session
         */
        Properties props = new Properties();
        props.setProperty("mail.host", "smtp.163.com");
        props.setProperty("mail.smtp.auth", "true");
    
        Authenticator auth = new Authenticator() {
          @Override
          protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("itcast_cxf", "itcast");
          }
        };
    
        Session session = Session.getInstance(props, auth);
    
        /*
         * 2. 创建MimeMessage
         */
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("itcast_cxf@163.com"));//设置发件人
        msg.setRecipients(RecipientType.TO, "itcast_cxf@126.com");//设置收件人
        msg.setRecipients(RecipientType.CC, "itcast_cxf@sohu.com");//设置抄送
        msg.setRecipients(RecipientType.BCC, "itcast_cxf@sina.com");//设置暗送
    
        msg.setSubject("这是来自ITCAST的测试邮件");
        msg.setContent("这就是一封垃圾邮件!", "text/html;charset=utf-8");
    
        /*
         * 3. 发邮件
         */
        Transport.send(msg);
      }
    
      /**
       * 带有附件的邮件!!!
       */
    
      public void sendMail2() throws Exception {
        /*
         * 1. 得到session
         */
        Properties props = new Properties();
        props.setProperty("mail.host", "smtp.163.com");
        props.setProperty("mail.smtp.auth", "true");
    
        Authenticator auth = new Authenticator() {
          @Override
          protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("itcast_cxf", "itcast");
          }
        };
    
        Session session = Session.getInstance(props, auth);
    
        /*
         * 2. 创建MimeMessage
         */
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("itcast_cxf@163.com"));//设置发件人
        msg.setRecipients(RecipientType.TO, "itcast_cxf@126.com");//设置收件人
    
        msg.setSubject("这是来自ITCAST的测试邮件有附件");
    
    
        
        /*
         * 当发送包含附件的邮件时,邮件体就为多部件形式!
         * 1. 创建一个多部件的部件内容!MimeMultipart
         *   MimeMultipart就是一个集合,用来装载多个主体部件!
         * 2. 我们需要创建两个主体部件,一个是文本内容的,另一个是附件的。
         *   主体部件叫MimeBodyPart
         * 3. 把MimeMultipart设置给MimeMessage的内容!
         */
        MimeMultipart list = new MimeMultipart();//创建多部分内容
    
        // 创建MimeBodyPart
        MimeBodyPart part1 = new MimeBodyPart();
        // 设置主体部件的内容
        part1.setContent("这是一封包含附件的垃圾邮件", "text/html;charset=utf-8");
        // 把主体部件添加到集合中
        list.addBodyPart(part1);
    
    
        // 创建MimeBodyPart
        MimeBodyPart part2 = new MimeBodyPart();
        part2.attachFile(new File("F:/f/白冰.jpg"));//设置附件的内容
        //设置显示的文件名称,其中encodeText用来处理中文乱码问题
        part2.setFileName(MimeUtility.encodeText("大美女.jpg"));
        list.addBodyPart(part2);
    
        msg.setContent(list);//把它设置给邮件作为邮件的内容。
    
    
        
    
        /*
         * 3. 发邮件
         */
        Transport.send(msg);    
      }
    
      public void sendMail3() throws Exception {
        /*
         * 1. 得到session
         */
        Session session = MailUtils.createSession("smtp.163.com", 
            "itcast_cxf", "itcast");
        /*
         * 2. 创建邮件对象
         */
        Mail mail = new Mail("itcast_cxf@163.com",
            "itcast_cxf@126.com,itcast_cxf@sina.com",
            "不是垃圾邮件能是什么呢?", "这里是正文");
    
        /*
         * 创建两个附件对象
         */
        AttachBean ab1 = new AttachBean(new File("F:/f/白冰.jpg"), "小美女.jpg");
        AttachBean ab2 = new AttachBean(new File("F:/f/big.jpg"), "我的羽绒服.jpg");
    
        // 添加到mail中
        mail.addAttach(ab1);
        mail.addAttach(ab2);
    
        /*
         * 3. 发送
         */
        MailUtils.send(session, mail);
      }
    }

    5. MailUtils

    public class MailUtils {
        public static Session createSession(String host, final String username, final String password) {
            Properties prop = new Properties();
            prop.setProperty("mail.host", host);// 指定主机
            prop.setProperty("mail.smtp.auth", "true");// 指定验证为true
    
            // 创建验证器
            Authenticator auth = new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            };
    
            // 获取session对象
            return Session.getInstance(prop, auth);
        }
    
        /**
         * 发送指定的邮件
         * 
         * @param mail
         */
        public static void send(Session session, final Mail mail) throws MessagingException,
                IOException {
    
            MimeMessage msg = new MimeMessage(session);// 创建邮件对象
            msg.setFrom(new InternetAddress(mail.getFrom()));// 设置发件人
            msg.addRecipients(RecipientType.TO, mail.getToAddress());// 设置收件人
    
            // 设置抄送
            String cc = mail.getCcAddress();
            if (!cc.isEmpty()) {
                msg.addRecipients(RecipientType.CC, cc);
            }
    
            // 设置暗送
            String bcc = mail.getBccAddress();
            if (!bcc.isEmpty()) {
                msg.addRecipients(RecipientType.BCC, bcc);
            }
    
            msg.setSubject(mail.getSubject());// 设置主题
    
            MimeMultipart parts = new MimeMultipart();// 创建部件集对象
    
            MimeBodyPart part = new MimeBodyPart();// 创建一个部件
            part.setContent(mail.getContent(), "text/html;charset=utf-8");// 设置邮件文本内容
            parts.addBodyPart(part);// 把部件添加到部件集中
    
            ///
    
            // 添加附件
            List<AttachBean> attachBeanList = mail.getAttachs();// 获取所有附件
            if (attachBeanList != null) {
                for (AttachBean attach : attachBeanList) {
                    MimeBodyPart attachPart = new MimeBodyPart();// 创建一个部件
                    attachPart.attachFile(attach.getFile());// 设置附件文件
                    attachPart.setFileName(MimeUtility.encodeText(attach
                            .getFileName()));// 设置附件文件名
                    parts.addBodyPart(attachPart);
                }
            }
    
            msg.setContent(parts);// 给邮件设置内容
            Transport.send(msg);// 发邮件
        }
    }
    文章来自:https://blog.csdn.net/axi295309066/article/details/52985134
    展开全文
  • JavaMail基本使用

    千次阅读 2016-10-23 20:10:44
    JavaMail基本使用基本概述 JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。我们可以基于JavaMail开发出类似于Microsoft ...

    JavaMail基本使用

    基本概述

    JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。我们可以基于JavaMail开发出类似于Microsoft Outlook的应用程序。

    虽然JavaMail是Sun的API之一,但它目前还没有被加在标准的java开发工具包中(Java Development Kit),这就意味着你在使用前必须另外下载JavaMail文件。除此以外,你还需要有Sun的JavaBeans Activation Framework (JAF)。JavaBeans Activation Framework的运行很复杂,在这里简单的说就是JavaMail的运行必须得依赖于它的支持。在Windows 2000下使用需要指定这些文件的路径,在其它的操作系统上也类似。

    JavaMail是可选包,因此如果需要使用的话你需要首先从java官网上下载。使用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中读取类似于邮件服务器,用户名和密码等信息。
    另外很好的实现了JavaMail API的框架有James、Spring Mail。

    ——《百度百科》

    电子邮件

    概述

    • 电子邮箱:向服务器申请了一块空间(硬盘的地址),存储着你申请的这个邮箱存放的数据。

      • 电子邮箱(E-mail地址)的获得需要在邮件服务器上进行申请 ,确切地说,电子邮箱其实就是用户在邮件服务器上申请的一个帐户。用户在邮件服务器上申请了一个帐号后,邮件服务器就会为这个帐号分配一定的空间,用户从而可以使用这个帐号以及空间,发送电子邮件和保存别人发送过来的电子邮件。
    • 邮件服务器:

      • 要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器。例如现在Internet很多提供邮件服务的厂商:sina、sohu、163等等他们都有自己的邮件服务器。
      • 这些服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中
      • 邮件服务器,按照提供的服务类型,可以分为发送邮件的服务器接收邮件的服务器

    邮件协议

    • SMTP协议-发邮件协议

      • 全称为Simple Mail Transfer Protocol(简单邮件传输协议),它定义了邮件客户端软件与SMTP服务器之间、以及两台SMTP服务器之间的通讯规则。
      • 端口号:25.
    • POP/POP3协议-收邮件协议

      • 全称为Post Office Protocol(邮局协议),它定义了邮件客户端软件与POP3服务器的通讯规则。服务器到客户的通讯规则。
      • 端口号:110.

    JavaMail使用

    package com.pc.user.utils;
    
    import java.util.Properties;
    
    import javax.mail.Authenticator;
    import javax.mail.Message;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMessage.RecipientType;
    
    import com.pc.user.domain.User;
    
    /**
     * 邮件工具类
     * 
     * @author Switch
     * @data 2016年10月23日
     * @version V1.0
     */
    public class MailUtils {
        /**
         * 发送邮件
         * 
         * @param user
         *            用户Bean
         */
        public static void sendMail(User user) {
            // Session对象(会话)
            Properties props = new Properties();
            // 邮件服务器在本机
            props.setProperty("mail.host", "localhost");
    
            // 邮件服务器在外网需要用下面两个配置替代
            // props.setProperty("mail.host", "smtp-mail.outlook.com");
            // 外网会强制验证
            props.setProperty("mail.smtp.auth", "true");
            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                public PasswordAuthentication getPasswordAuthentication() {
                    // 邮件服务器在本机
                    return new PasswordAuthentication("Admin@store.com", "123456");
    
                    // 邮件服务器在外网
                    // return new PasswordAuthentication("*****@163.com","123456");
                }
            });
    
            // Message对象
            Message message = new MimeMessage(session);
            try {
                // 设置发件人:(最好是与登录名相同)
                message.setFrom(new InternetAddress("Admin@store.com"));
                // 设置收件人:
                message.addRecipient(RecipientType.TO, new InternetAddress(user.getEmail()));
                // 设置主题:
                message.setSubject("生日快乐");
                // 设置内容:
                message.setContent("尊敬的用户,祝您生日快乐!", "text/html;charset=UTF-8");
                // 3.Transport对象:
                Transport.send(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    PS:JavaMail发送邮件案例:GitHub

    展开全文
  • JavaMail 实例

    2019-09-11 11:48:12
    1.开启pop3服务器 ... 2.MailProperties import org.springframework.stereotype.Component; /** * 发送邮件公共属性 * @time 2017-8-8 17:03:08 * */ @Co...

    1.开启pop3服务器

    https://jingyan.baidu.com/article/c85b7a64be9284003bac9535.html

    2.MailProperties

    import org.springframework.stereotype.Component;
    
    /**
     * 发送邮件公共属性
     * @time 2017-8-8 17:03:08
     *
     */
    @Component
    //@ConfigurationProperties(prefix="email")
    public class MailProperties {
    	private String  smtp = "smtp.qq.com";
    	private String	from = "xx@qq.com";
    	private String 	userName = "xx@qq.com";
    	private String 	password = "xxx";
    	private int port = 465;
    	public String getSmtp() {
    		return smtp;
    	}
    	public void setSmtp(String smtp) {
    		this.smtp = smtp;
    	}
    	public String getFrom() {
    		return from;
    	}
    	public void setFrom(String from) {
    		this.from = from;
    	}
    	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 int getPort() {
    		return port;
    	}
    
    	public void setPort(int port) {
    		this.port = port;
    	}
    }

    3.Mail方法类

    
    
    import com.alibaba.fastjson.JSONObject;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.activation.DataHandler;
    import javax.activation.FileDataSource;
    import javax.mail.*;
    import javax.mail.internet.*;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Properties;
    
    @Component
    public class Mail {
    
        @Autowired
        MailProperties getProperties;
    
        protected final Logger logger = LoggerFactory.getLogger(getClass());
    
        private MimeMessage mimeMsg; //MIME邮件对象
        private Session session; //邮件会话对象
        private Properties props; //系统属性
        private boolean needAuth = false; //smtp是否需要认证
        //smtp认证用户名和密码
        private String username;
        private String password;
        private Multipart mp; //Multipart对象,邮件内容,标题,附件等内容均添加到其中后再生成MimeMessage对象
    
        /**
         * Constructor
         * @param smtp 邮件发送服务器
         */
        public Mail(String smtp,int port){
            setSmtpHost(smtp,port);
            createMimeMessage();
        }
    
        public Mail(){
    
        }
    
        /**
         * 设置邮件发送服务器
         * @param hostName String
         */
        public void setSmtpHost(String hostName,int port) {
            logger.info("设置系统属性:mail.smtp.host = "+hostName);
            if(props == null)
                props = System.getProperties(); //获得系统属性对象
            props.put("mail.smtp.host",hostName); //设置SMTP主机
            //开启加密传输
            if(port==465){
                logger.info("使用465端口发送");
                props.setProperty("mail.smtp.port",String.valueOf(port));
                props.setProperty("mail.smtp.auth", "true");//开启认证
                props.setProperty("mail.smtp.socketFactory.port", String.valueOf(port));//设置ssl端口
                props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            }
        }
    
    
        /**
         * 创建MIME邮件对象
         * @return
         */
        public boolean createMimeMessage()
        {
            try {
                logger.info("准备获取邮件会话对象!");
                session = Session.getDefaultInstance(props,null); //获得邮件会话对象
            }
            catch(Exception e){
                JSONObject json1=new JSONObject();
                json1.put("code",-1);
                json1.put("msg","获取邮件会话对象时发生错误!");
                logger.error(json1.toJSONString(),e);
                return false;
            }
    
            logger.info("准备创建MIME邮件对象!");
            try {
                mimeMsg = new MimeMessage(session); //创建MIME邮件对象
                mp = new MimeMultipart();
    
                return true;
            } catch(Exception e){
                JSONObject json1=new JSONObject();
                json1.put("code",-1);
                json1.put("msg","创建MIME邮件对象失败!");
                logger.error(json1.toJSONString(),e);
                return false;
            }
        }
    
        /**
         * 设置SMTP是否需要验证
         * @param need
         */
        public void setNeedAuth(boolean need) {
            logger.info("设置smtp身份认证:mail.smtp.auth = "+need);
            if(props == null) props = System.getProperties();
            if(need){
                props.put("mail.smtp.auth","true");
            }else{
                props.put("mail.smtp.auth","false");
            }
        }
    
        /**
         * 设置用户名和密码
         * @param name
         * @param pass
         */
        public void setNamePass(String name,String pass) {
            username = name;
            password = pass;
        }
    
        /**
         * 设置邮件主题
         * @param mailSubject
         * @return
         */
        public boolean setSubject(String mailSubject) {
            logger.info("设置邮件主题!");
            try{
                mimeMsg.setSubject(mailSubject);
                return true;
            }
            catch(Exception e) {
                JSONObject json1=new JSONObject();
                json1.put("code",-1);
                json1.put("msg","设置邮件主题发生错误!");
                logger.error(json1.toJSONString(),e);
                return false;
            }
        }
    
        /**
         * 设置邮件正文
         * @param mailBody String
         */
        public boolean setBody(String mailBody) {
            try{
                BodyPart bp = new MimeBodyPart();
                bp.setContent(""+mailBody,"text/html;charset=GBK");
                mp.addBodyPart(bp);
    
                return true;
            } catch(Exception e){
                JSONObject json1=new JSONObject();
                json1.put("code",-1);
                json1.put("msg","设置邮件正文时发生错误!");
                logger.error(json1.toJSONString(),e);
                return false;
            }
        }
        /**
         * 添加附件
         * @param filename String
         */
        public boolean addFileAffix(String filename) {
    
            logger.info("增加邮件附件:"+ filename);
            try{
                BodyPart bp = new MimeBodyPart();
                FileDataSource fileds = new FileDataSource(filename);
                bp.setDataHandler(new DataHandler(fileds));
                bp.setFileName(fileds.getName());
    
                mp.addBodyPart(bp);
    
                return true;
            } catch(Exception e){
                JSONObject json1=new JSONObject();
                json1.put("code",-1);
                json1.put("msg","增加邮件附件!发生错误");
                logger.error(json1.toJSONString(),e);
                logger.error("增加邮件附件:"+filename+"发生错误!",e.getMessage(),e);
                return false;
            }
        }
    
        /**
         * 设置发信人
         * @param from String
         */
        public boolean setFrom(String from) {
            logger.info("设置发信人!");
            try{
                mimeMsg.setFrom(new InternetAddress(from)); //设置发信人
                return true;
            } catch(Exception e) {
                JSONObject json=new JSONObject();
                json.put("code",-1);
                logger.error(json.toJSONString(),e);
                return false;
            }
        }
        /**
         * 设置收信人
         * @param to String
         */
        public boolean setTo(String to){
            if(to == null||to.equals(""))return false;
            if(to.indexOf(",")>0){
                try{
                    List<InternetAddress> list = new ArrayList<InternetAddress>();
                    String []median=to.split(",");//对输入的多个邮件进行逗号分割
                    for(int i=0;i<median.length;i++){
                        list.add(new InternetAddress(median[i]));
                    }
                    InternetAddress[] address =(InternetAddress[])list.toArray(new InternetAddress[list.size()]);
                    mimeMsg.setRecipients(Message.RecipientType.TO, address);
                    return true;
                } catch(Exception e) {
                    JSONObject json=new JSONObject();
                    json.put("code",-1);
                    logger.error(json.toJSONString(),e);
                    return false;
                }
            }else{
                try{
                    mimeMsg.setRecipients(Message.RecipientType.TO,InternetAddress.parse(to));
                    return true;
                } catch(Exception e) {
                    JSONObject json=new JSONObject();
                    json.put("code",-1);
                    logger.error(json.toJSONString(),e);
                    return false;
                }
            }
    
        }
    
        /**
         * 设置抄送人
         * @param copyto String
         */
        public boolean setCopyTo(String copyto)
        {
            if(copyto == null)
                return false;
            try{
                mimeMsg.setRecipients(Message.RecipientType.CC,(Address[])InternetAddress.parse(copyto));
                return true;
            }
            catch(Exception e){
                JSONObject json=new JSONObject();
                json.put("code",-1);
                logger.error(json.toJSONString(),e);
                return false;
            }
        }
    
        /**
         * 发送邮件
         */
        public boolean sendOut()
        {
            try{
                mimeMsg.setContent(mp);
                mimeMsg.saveChanges();
                logger.info("正在发送邮件....");
    
                Session mailSession = Session.getInstance(props,null);
                Transport transport = mailSession.getTransport("smtp");
                transport.connect((String)props.get("mail.smtp.host"),username,password);
                transport.sendMessage(mimeMsg,mimeMsg.getRecipients(Message.RecipientType.TO));
                Address[] address=mimeMsg.getRecipients(Message.RecipientType.CC);
                if(address!=null){
                    transport.sendMessage(mimeMsg,address);
                }
                //transport.send(mimeMsg);
    
                logger.info("发送邮件成功!");
                transport.close();
    
                return true;
            } catch(Exception e) {
                JSONObject json=new JSONObject();
                json.put("code",-1);
                json.put("msg","邮件发送失败!");
                logger.error(json.toJSONString(),e);
                return false;
            }
        }
    
        /**
         * 调用sendOut方法完成邮件发送
         * @param smtp
         * @param from
         * @param to
         * @param subject
         * @param content
         * @param username
         * @param password
         * @return boolean
         */
        private boolean send(String smtp,String from,String to,String subject,String content,String username,String password,int port) {
            logger.info("send收件人邮箱:"+to);
            Mail theMail = new Mail(smtp,port);
            theMail.setNeedAuth(true); //需要验证
    
            if(!theMail.setSubject(subject)) return false;
            if(!theMail.setBody(content)) return false;
            if(!theMail.setTo(to)) return false;
            if(!theMail.setFrom(from)) return false;
            theMail.setNamePass(username,password);
    
            if(!theMail.sendOut()) return false;
            return true;
        }
    
        /**
         * 发送邮件
         * @param to 发送给
         * @param subject 标题
         * @param content 正文
         * @return
         */
        public boolean sendMail(String to,String subject,String content){
            return send(getProperties.getSmtp(),getProperties.getFrom(), to, subject, content,getProperties.getUserName(), getProperties.getPassword(),getProperties.getPort());
        }
    
        /**
         * 发送邮件
         * @param to 发送给
         * @param subject 标题
         * @param content 正文
         * @param copyTo 抄送给
         * @return
         */
        public boolean sendMail(String to,String copyTo,String subject,String content){
            return sendAndCc( getProperties.getSmtp(),getProperties.getFrom(), to, copyTo ,subject, content, getProperties.getUserName(), getProperties.getPassword(),getProperties.getPort());
        }
    
        /**
         * 发送邮件
         * @param to 发送给
         * @param subject 标题
         * @param content 正文
         * @param copyTo 抄送给
         * @param fileName 附件
         * @return
         */
        public boolean sendMail(String to,String copyTo,String subject,String content,String fileName){
            return sendAndCc(getProperties.getSmtp(), getProperties.getFrom(), to, copyTo ,subject, content,  getProperties.getUserName(), getProperties.getPassword(),fileName,getProperties.getPort());
        }
    
        /**
         * 调用sendOut方法完成邮件发送,带抄送
         * @param smtp
         * @param from
         * @param to
         * @param copyto
         * @param subject
         * @param content
         * @param username
         * @param password
         * @return boolean
         */
        public boolean sendAndCc(String smtp,String from,String to,String copyto,String subject,String content,String username,String password,int port) {
            logger.info("sendAndCc收件人邮箱:"+to,"抄送人邮箱:"+copyto);
            Mail theMail = new Mail(smtp,port);
            theMail.setNeedAuth(true); //需要验证
    
            if(!theMail.setSubject(subject)) return false;
            if(!theMail.setBody(content)) return false;
            if(!theMail.setTo(to)) return false;
            if(!theMail.setCopyTo(copyto)) return false;
            if(!theMail.setFrom(from)) return false;
            theMail.setNamePass(username,password);
    
            if(!theMail.sendOut()) return false;
            return true;
        }
    
    
        /**
         * 调用sendOut方法完成邮件发送,带附件和抄送
         * @param smtp
         * @param from
         * @param to
         * @param copyto
         * @param subject
         * @param content
         * @param username
         * @param password
         * @param filename
         * @return
         */
        public boolean sendAndCc(String smtp,String from,String to,String copyto,String subject,String content,String username,String password,String filename,int port) {
            logger.info("sendAndCc收件人邮箱:"+to,"抄送人邮箱:"+copyto);
            Mail theMail = new Mail(smtp,port);
            theMail.setNeedAuth(true); //需要验证
    
            if(!theMail.setSubject(subject)) return false;
            if(!theMail.setBody(content)) return false;
            if(!theMail.addFileAffix(filename)) return false;
            if(!theMail.setTo(to)) return false;
            if(!theMail.setCopyTo(copyto)) return false;
            if(!theMail.setFrom(from)) return false;
            theMail.setNamePass(username,password);
    
            if(!theMail.sendOut()) return false;
            return true;
        }
    
        public synchronized boolean sendMessageForHtml(String to,String subject, String messageText,String[] ccs) throws MessagingException,
                java.io.UnsupportedEncodingException {
            logger.info("sendMessageForHtml收件人邮箱:"+to);
            java.util.Properties props = new java.util.Properties();
            props.setProperty("mail.smtp.auth", "true");// 指定是否需要SMTP验证
            props.setProperty("mail.smtp.host", getProperties.getSmtp());// 指定SMTP服务器
            //开启加密传输
            if(getProperties.getPort()==465){
                logger.info("使用465端口发送");
                props.setProperty("mail.smtp.port",String.valueOf(getProperties.getPort()));
                props.setProperty("mail.smtp.auth", "true");//开启认证
                props.setProperty("mail.smtp.socketFactory.port", String.valueOf(getProperties.getPort()));//设置ssl端口
                props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            }
            props.put("mail.transport.protocol", "smtp");
            Session mailSession = Session.getDefaultInstance(props);
            mailSession.setDebug(false);// 是否在控制台显示debug信息
    
            // Step 2: Construct the message
            InternetAddress fromAddress = new InternetAddress(getProperties.getFrom());
            InternetAddress toAddress = new InternetAddress(to);
    
            MimeMessage testMessage = new MimeMessage(mailSession);
            testMessage.setFrom(fromAddress);
            testMessage.addRecipient(javax.mail.Message.RecipientType.TO, toAddress);
            testMessage.setSentDate(new java.util.Date());
            testMessage.setSubject(MimeUtility.encodeText(subject, "gb2312", "B"));
            if(ccs!=null){
                for(String cc:ccs){
                    testMessage.addRecipients(Message.RecipientType.CC,cc);
                }
    
            }
            testMessage.setContent(messageText, "text/html;charset=gb2312");
    
            Transport transport = mailSession.getTransport("smtp");
            transport.connect(getProperties.getSmtp(),  getProperties.getUserName(), getProperties.getPassword());
            transport.sendMessage(testMessage, testMessage.getAllRecipients());
            transport.close();
    
            return true;
        }
    
    }
    
    
    

    调用 sendMail(String to,String subject,String content)就可以发送了

    展开全文
  • 基于JavaMail的Java邮件发送:简单邮件发送

    万次阅读 多人点赞 2016-06-14 21:56:35
    本文链接: ... ...但这些应用不可能和我们自己平时发邮件一样,先打开浏览器,登录邮箱,创建邮件再发送。本文将简单介绍如何通过 Java 代码来创建电子邮件,并连接邮件服务器发...
  • javamail 收发邮件

    千次阅读 2018-07-21 17:16:16
    邮件协议   1 收发邮件  发邮件大家都会吧!发邮件是从客户端把邮件发送到邮件服务器,收邮件是把邮件服务器的邮件下载到客户端。 ...这些网站都有自己的邮件服务器。...SMTP:(Simple Mail T...
  • JavaMail的大坑

    千次阅读 2017-11-12 17:36:31
    JavaMail 超时 卡死 参数 163.com
  • javamail 中文API文档

    2012-06-01 17:44:27
    javamail中文API文档 方法解释详细。
  • javaMail
  • javamail 发送邮件

    千次阅读 2018-09-30 11:49:21
    import java.util.Date; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session;...import javax.mail.Transport;...import javax.mail.internet.....
  • 利用java实现发送邮件

    万次阅读 多人点赞 2017-11-14 15:01:31
    很显然这些应用不可能和我们自己平时发邮件一样,先打开浏览器,登录邮箱,创建邮件再发送。本文将简单介绍如何通过 Java 代码来创建电子邮件,并连接邮件服务器发送邮件。电子邮件协议 电子邮件在网络中传输和网页...
  • 一、Java Mail概述: Java Mail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类。但它并没有包含在JDK中,而是作为J2EE的一部分。 厂商所提供的Java Mail服务程序可以有选择地实现某些邮件...
  • javaEmail发送邮件

    千次阅读 2019-02-26 11:48:26
    效果如下: 一.电子邮件协议: SMTP 简单邮件传输 SMTP是Simple Mail Transfer Protocol的简称,即简单邮件传输协议。该协议定义了邮件客户端软件和SMTP服务器之间,以及两台SMTP服务器之间的通信规则。...
  • 今天网站要用到发送邮件功能,于是乎就研究了下如何利用java发送邮件。其实网站发送邮件的功能特别重要,比如激活的时候,很多网站激活都需要通过邮件激活的。对于java来说可以通过javamail这个包来实现。下面给出一...
  • Java 实现邮件发送,使用 JavaMail 和 Spring 实现 一、使用 JavaMail JavaMailJava 处理电子邮件相关的编程接口,但是没有被加在标准的Java开发工具包中(Java Development Kit),所以我们使用 JavaMail ...
  • Java 发送邮件

    千次阅读 2018-08-06 09:00:16
    使用Java应用程序发送 E-mail 十分简单,但是首先你应该在你的机器上安装 JavaMail API 和Java Activation Framework (JAF) 。 您可以从 Java 网站下载最新版本的 JavaMail,打开网页右侧有个 Downloads 链接,点击...
  • Java 发送邮件的几种方式

    万次阅读 多人点赞 2018-10-24 13:38:07
    发送文件的项目地址(free):https://download.csdn.net/download/qq_36474549/10741073 导入jar包:activation-1.1.jar...发送一封只包含文本的简单邮件 SendEmail_text.java  2.发送包含内嵌图片的邮件 Send...
  • Java发送邮件的几种方式

    万次阅读 多人点赞 2017-05-31 16:21:55
    发送邮件就要用到java中的JavaMail,关于JavaMailAPI的详解呢在 (http://blog.csdn.net/imain/article/details/1453677“)中有非常详尽的介绍,我就直接上代码了。 1:使用JavaMail发送邮件 // 1.创建一个...
  • 最近项目中有个需求,需要写一个接口,即在本地局域网内发送邮件。于是上网百度了一番,有很多借鉴,但大部分都是在本地发送邮件到外网服务器,比如什么QQ,新浪或搜狐邮箱等。但还是吸取了不少有用的东西,也可谓是...
  • java 发送邮件(并添加附件)

    千次阅读 2016-02-26 15:23:22
    实现java发送邮件的过程大体有以下几步: 准备一个properties文件,该文件中存放SMTP服务器地址等参数。利用properties创建一个Session对象利用Session创建Message对象,然后设置邮件主题和正文利用Transport对象...
  • java发送邮件谁能解决javaee6以下版本代码放到linux环境件人和主题中文显示?不使用MimeUtility
  • 复杂邮件发送,主要是创建邮件时,内容的设置不同: 代码实现: package top.jacktu.test; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; import javax....
  • Java发送邮件,html邮件模板分享

    千次阅读 2019-09-24 12:47:27
    以前有用JavaMail写过发送html邮件,当时在benchmark网站自己设计了个html模板,分享记录一下。 预览: 访客端 以上模板的html文件下载 下载点这里 云盘密码: emailpw1 站长端 以上模板的html...
  • java发送邮件一般使用在注册账号时、或其他通知信息时,网站会使用邮件定时发送、或触发发送邮件通知用户; 我是用的是maven开发,所以需要在pom文件中
  • java发送邮件&&使用HtmlEmail发送邮件

    千次阅读 2019-04-28 17:42:06
    java原生发送qq邮箱 首先要有QQ邮箱的授权码,如果有就直接看代码。 1.登录QQ邮箱,找到设置 2.选择账户选项,往下找到IMAP服务。 3.开启服务获得授权码,或已经开启缺不知道,可以重新生成授权码。 public ...
  • javamail smtpToday we will look into JavaMail Example to send email in java programs. Sending emails is one of the common tasks in real life applications and that’s why Java provides robust JavaMail ...
  • java发送邮件(一封邮件发给多人)

    千次阅读 2017-05-12 15:00:56
    需要以下jar包的支持 mail.jar 下载地址 http://static.runoob.com/download/mail.jar
  • BUG描述:本地测试,正常发送邮件。部署到linux服务器后,发送邮件无主题,无收件人,正文中是乱码(准确说是QP编码)。   本以为 是服务器编码问题,各种设置编码,都不行,最终找到了原因,jar包冲突.大家可以...
  • Java实现邮件发送

    万次阅读 多人点赞 2019-07-20 16:03:19
    Java实现邮件发送 一、邮件服务器与传输协议 要在网络上实现邮件功能,必须要有专门的邮件服务器。这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱...
  • java发送邮件 携带excel附件

    千次阅读 2018-09-14 18:25:03
    poi的介绍我就不多说了,详情见: https://blog.csdn.net/fz13768884254/article/details/82706936 ... 代码如下: import base.BaseTest; import org.apache.poi.hss...

空空如也

1 2 3 4 5 ... 20
收藏数 162,014
精华内容 64,805
关键字:

javamail

java 订阅