JavaMail 示例 - 使用 SMTP 在 Java 中发送邮件

今天我们将探讨JavaMail示例以在Java程序中发送电子邮件。发送电子邮件是现实生活应用程序中常见的任务之一,这就是为什么Java提供了强大的JavaMail API,我们可以使用它来使用SMTP服务器发送电子邮件。

雅虎示例

javamail example, send mail in java, java smtp, java send email Today we will learn how to use JavaMail API to send emails using SMTP server with no authentication, TLS and SSL authentication and how to send attachments and attach and use images in the email body. For TLS and SSL authentication, I am using GMail SMTP server because it supports both of them. You can also choose to go for a Java mail server depending on your project needs. JavaMail API is not part of standard JDK, so you will have to download it from it's official website i.e JavaMail Home Page. Download the latest version of the JavaMail reference implementation and include it in your project build path. The jar file name will be javax.mail.jar. If you are using Maven based project, just add below dependency in your project.

1<dependency>
2    <groupId>com.sun.mail</groupId>
3    <artifactId>javax.mail</artifactId>
4    <version>1.5.5</version>
5</dependency>

Java 发送电子邮件程序包含以下步骤:

  1. 创建「javax.mail.Session」对象
  2. 创建「javax.mail.internet.MimeMessage」对象,我们必须在该对象中设置不同的属性,如收件人电子邮件地址、电子邮件主题、回复电子邮件、电子邮件体、附件等
  3. 使用「javax.mail.Transport」发送电子邮件。

创建会话的逻辑取决于SMTP服务器的类型,例如,如果SMTP服务器不需要任何身份验证,我们可以用一些简单的属性创建Session对象,而如果它需要TLS或SSL身份验证,那么创建的逻辑将有所不同。

JavaMail 示例程序

我们的 EmailUtil 类具有发送电子邮件的单一方法看起来如下,它需要 javax.mail.Session 和其他一些必要的字段作为参数。 为了保持简单,一些参数难以编码,但您可以扩展此方法来传输它们或从一些 config 文件中读取它。

 1package com.journaldev.mail;
 2
 3import java.io.UnsupportedEncodingException;
 4import java.util.Date;
 5
 6import javax.activation.DataHandler;
 7import javax.activation.DataSource;
 8import javax.activation.FileDataSource;
 9import javax.mail.BodyPart;
10import javax.mail.Message;
11import javax.mail.MessagingException;
12import javax.mail.Multipart;
13import javax.mail.Session;
14import javax.mail.Transport;
15import javax.mail.internet.InternetAddress;
16import javax.mail.internet.MimeBodyPart;
17import javax.mail.internet.MimeMessage;
18import javax.mail.internet.MimeMultipart;
19
20public class EmailUtil {
21
22    /**
23     * Utility method to send simple HTML email
24     * @param session
25     * @param toEmail
26     * @param subject
27     * @param body
28     */
29    public static void sendEmail(Session session, String toEmail, String subject, String body){
30    	try
31        {
32          MimeMessage msg = new MimeMessage(session);
33          //set message headers
34          msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
35          msg.addHeader("format", "flowed");
36          msg.addHeader("Content-Transfer-Encoding", "8bit");
37
38          msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));
39
40          msg.setReplyTo(InternetAddress.parse("[email protected]", false));
41
42          msg.setSubject(subject, "UTF-8");
43
44          msg.setText(body, "UTF-8");
45
46          msg.setSentDate(new Date());
47
48          msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
49          System.out.println("Message is ready");
50    	  Transport.send(msg);  
51
52          System.out.println("EMail Sent Successfully!!");
53        }
54        catch (Exception e) {
55          e.printStackTrace();
56        }
57    }
58}

请注意,我在MimeMessage中设置一些标题属性,这些属性被电子邮件客户端使用来正确渲染和显示电子邮件消息。

使用SMTP在Java中发送邮件而无需身份验证

 1package com.journaldev.mail;
 2
 3import java.util.Properties;
 4
 5import javax.mail.Session;
 6
 7public class SimpleEmail {
 8    
 9    public static void main(String[] args) {
10    	
11        System.out.println("SimpleEmail Start");
12    	
13        String smtpHostServer = "smtp.example.com";
14        String emailID = "[email protected]";
15        
16        Properties props = System.getProperties();
17
18        props.put("mail.smtp.host", smtpHostServer);
19
20        Session session = Session.getInstance(props, null);
21        
22        EmailUtil.sendEmail(session, emailID,"SimpleEmail Testing Subject", "SimpleEmail Testing Body");
23    }
24
25}

请注意,我正在使用 Session.getInstance() 来通过 Properties 对象获取 Session 对象,我们需要与 SMTP 服务器主机设置 mail.smtp.host 属性,如果 SMTP 服务器在默认端口(25)上不运行,那么您还需要设置 mail.smtp.port 属性。只需使用您的无身份验证 SMTP 服务器运行这个程序,并将接收电子邮件标识设置为您的电子邮件标识,您将很快获得电子邮件。该程序很容易理解和工作,但在现实生活中,大多数 SMTP 服务器使用某种身份验证,如 TLS 或 SSL 身份验证。所以我们现在将看到如何为这些身份验证协议创建 Session 对象。

在 Java SMTP 中使用 TLS 身份验证发送电子邮件

 1package com.journaldev.mail;
 2
 3import java.util.Properties;
 4
 5import javax.mail.Authenticator;
 6import javax.mail.PasswordAuthentication;
 7import javax.mail.Session;
 8
 9public class TLSEmail {
10
11    /**
12       Outgoing Mail (SMTP) Server
13       requires TLS or SSL: smtp.gmail.com (use authentication)
14       Use Authentication: Yes
15       Port for TLS/STARTTLS: 587
16     */
17    public static void main(String[] args) {
18    	final String fromEmail = "[email protected]"; //requires valid gmail id
19    	final String password = "mypassword"; // correct password for gmail id
20    	final String toEmail = "[email protected]"; // can be any email id 
21    	
22    	System.out.println("TLSEmail Start");
23    	Properties props = new Properties();
24    	props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
25    	props.put("mail.smtp.port", "587"); //TLS Port
26    	props.put("mail.smtp.auth", "true"); //enable authentication
27    	props.put("mail.smtp.starttls.enable", "true"); //enable STARTTLS
28    	
29                //create Authenticator object to pass in Session.getInstance argument
30    	Authenticator auth = new Authenticator() {
31    		//override the getPasswordAuthentication method
32    		protected PasswordAuthentication getPasswordAuthentication() {
33    			return new PasswordAuthentication(fromEmail, password);
34    		}
35    	};
36    	Session session = Session.getInstance(props, auth);
37    	
38    	EmailUtil.sendEmail(session, toEmail,"TLSEmail Testing Subject", "TLSEmail Testing Body");
39    	
40    }
41
42    
43}

由于我正在使用GMail SMTP服务器,它是可访问的所有人,你可以设置正确的变量在上面的程序,并为自己运行。

Java SMTP 示例与 SSL 身份验证

 1package com.journaldev.mail;
 2
 3import java.util.Properties;
 4
 5import javax.mail.Authenticator;
 6import javax.mail.PasswordAuthentication;
 7import javax.mail.Session;
 8
 9public class SSLEmail {
10
11    /**
12       Outgoing Mail (SMTP) Server
13       requires TLS or SSL: smtp.gmail.com (use authentication)
14       Use Authentication: Yes
15       Port for SSL: 465
16     */
17    public static void main(String[] args) {
18    	final String fromEmail = "[email protected]"; //requires valid gmail id
19    	final String password = "mypassword"; // correct password for gmail id
20    	final String toEmail = "[email protected]"; // can be any email id 
21    	
22    	System.out.println("SSLEmail Start");
23    	Properties props = new Properties();
24    	props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
25    	props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
26    	props.put("mail.smtp.socketFactory.class",
27    			"javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
28    	props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
29    	props.put("mail.smtp.port", "465"); //SMTP Port
30    	
31    	Authenticator auth = new Authenticator() {
32    		//override the getPasswordAuthentication method
33    		protected PasswordAuthentication getPasswordAuthentication() {
34    			return new PasswordAuthentication(fromEmail, password);
35    		}
36    	};
37    	
38    	Session session = Session.getDefaultInstance(props, auth);
39    	System.out.println("Session created");
40            EmailUtil.sendEmail(session, toEmail,"SSLEmail Testing Subject", "SSLEmail Testing Body");
41
42            EmailUtil.sendAttachmentEmail(session, toEmail,"SSLEmail Testing Subject with Attachment", "SSLEmail Testing Body with Attachment");
43
44            EmailUtil.sendImageEmail(session, toEmail,"SSLEmail Testing Subject with Image", "SSLEmail Testing Body with Image");
45
46    }
47
48}

该程序几乎与TLS身份验证相同,只有一些属性不同. 正如你可以看到的那样,我正在从EmailUtil类呼叫一些其他方法以发送附件和图像在电子邮件中,但我还没有定义它们。

JavaMail 示例 - 用 Java 发送附件的邮件

要将文件发送为附件,我们需要创建一个对象,即javax.mail.internet.MimeBodyPartjavax.mail.internet.MimeMultipart。 首先在电子邮件中添加文本消息的身体部分,然后使用FileDataSource将文件附加到多部分体的第二部分。

 1/**
 2 * Utility method to send email with attachment
 3 * @param session
 4 * @param toEmail
 5 * @param subject
 6 * @param body
 7 */
 8public static void sendAttachmentEmail(Session session, String toEmail, String subject, String body){
 9    try{
10         MimeMessage msg = new MimeMessage(session);
11         msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
12         msg.addHeader("format", "flowed");
13         msg.addHeader("Content-Transfer-Encoding", "8bit");
14          
15         msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));
16
17         msg.setReplyTo(InternetAddress.parse("[email protected]", false));
18
19         msg.setSubject(subject, "UTF-8");
20
21         msg.setSentDate(new Date());
22
23         msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
24          
25         // Create the message body part
26         BodyPart messageBodyPart = new MimeBodyPart();
27
28         // Fill the message
29         messageBodyPart.setText(body);
30
31         // Create a multipart message for attachment
32         Multipart multipart = new MimeMultipart();
33
34         // Set text message part
35         multipart.addBodyPart(messageBodyPart);
36
37         // Second part is attachment
38         messageBodyPart = new MimeBodyPart();
39         String filename = "abc.txt";
40         DataSource source = new FileDataSource(filename);
41         messageBodyPart.setDataHandler(new DataHandler(source));
42         messageBodyPart.setFileName(filename);
43         multipart.addBodyPart(messageBodyPart);
44
45         // Send the complete message parts
46         msg.setContent(multipart);
47
48         // Send message
49         Transport.send(msg);
50         System.out.println("EMail Sent Successfully with attachment!!");
51      }catch (MessagingException e) {
52         e.printStackTrace();
53      } catch (UnsupportedEncodingException e) {
54    	 e.printStackTrace();
55    }
56}

该程序可能看起来很复杂,但它很简单,只需为文本消息创建一个身体部件和附件的另一个身体部件,然后将其添加到多部件。

JavaMail 示例 - 用图片发送 Java 邮件

由于我们可以创建 HTML 体消息,如果图像文件位于某个服务器位置,我们可以使用 img 元素来显示它们在邮件中,但有时我们想要在电子邮件中添加图像,然后在电子邮件体中使用它。

 1/**
 2 * Utility method to send image in email body
 3 * @param session
 4 * @param toEmail
 5 * @param subject
 6 * @param body
 7 */
 8public static void sendImageEmail(Session session, String toEmail, String subject, String body){
 9    try{
10         MimeMessage msg = new MimeMessage(session);
11         msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
12         msg.addHeader("format", "flowed");
13         msg.addHeader("Content-Transfer-Encoding", "8bit");
14          
15         msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));
16
17         msg.setReplyTo(InternetAddress.parse("[email protected]", false));
18
19         msg.setSubject(subject, "UTF-8");
20
21         msg.setSentDate(new Date());
22
23         msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
24          
25         // Create the message body part
26         BodyPart messageBodyPart = new MimeBodyPart();
27
28         messageBodyPart.setText(body);
29
30         // Create a multipart message for attachment
31         Multipart multipart = new MimeMultipart();
32
33         // Set text message part
34         multipart.addBodyPart(messageBodyPart);
35
36         // Second part is image attachment
37         messageBodyPart = new MimeBodyPart();
38         String filename = "image.png";
39         DataSource source = new FileDataSource(filename);
40         messageBodyPart.setDataHandler(new DataHandler(source));
41         messageBodyPart.setFileName(filename);
42         //Trick is to add the content-id header here
43         messageBodyPart.setHeader("Content-ID", "image_id");
44         multipart.addBodyPart(messageBodyPart);
45
46         //third part for displaying image in the email body
47         messageBodyPart = new MimeBodyPart();
48         messageBodyPart.setContent("<h1>Attached Image</h1>" +
49        		     "<img src='cid:image_id'>", "text/html");
50         multipart.addBodyPart(messageBodyPart);
51
52         //Set the multipart message to the email message
53         msg.setContent(multipart);
54
55         // Send message
56         Transport.send(msg);
57         System.out.println("EMail Sent Successfully with image!!");
58      }catch (MessagingException e) {
59         e.printStackTrace();
60      } catch (UnsupportedEncodingException e) {
61    	 e.printStackTrace();
62    }
63}

JavaMail API 故障排除技巧

  1. `java.net.unknownHostException'在您的系统无法解析SMTP服务器的IP地址时,可能会错误或无法从您的网络访问. 例如,GMail SMTP服务器是 smtp.gmail.com,如果我使用 smtp.google.com,我会得到这个例外. 如果主机名正确,请尝试通过命令行拨打服务器,以确保从您的系统可以访问. __ pankaj@Pankaj:~/CODE$ ping smtp.gmail.com pan. PING gmail-smtp-msa.l.google.com (74.125.129.108): 56个字节(- ) 64个字节出自74.125.129.108: icmp_seq=0 ttl=46时间=38.308个字节出自74.125.129.108: icmp_seq=3ttl=46时间=53.153个字节出自74.125.108: ic-seq=1 ttl=46时间=42.247个字节出自74.125.108: icmp_seq=2 ttl=46时间=38.164个字节出自74.125.129.108: ic_seq=3tl=53.153个字节出自- 422页出自- 2 如果您的程序卡在 Transport () 方法呼叫中, 请检查 SMTP 端口是否正确 。 如果正确的话, 请使用 telnet 来验证它是否可从您的机器中访问, 您将会像下面一样得到输出 。 @ _) pankaj@ Pankaj:~/CODE$ telnet smtp.gmail.com 587 尝试2607:f8b0:400e:c02::6d. 连接到gmail-smtp-msa.l.google.com. 逃脱字符为"^". 220 mx.google.com MENTP sx8sm78485186pab.5 - gsmtp HELO 250 mx.google.com 在您服务中 _

这就是JavaMail的例子,用SMTP服务器用不同的身份验证协议,附件和图像发送Java邮件,我希望它能解决您在Java程序中发送电子邮件的所有需求。

Published At
Categories with 技术
Tagged with
comments powered by Disqus