JavaMail示例–使用SMTP以Java发送邮件
今天,我们将研究JavaMail Example在Java程序中发送电子邮件。
发送电子邮件是现实生活中应用程序中的常见任务之一,这就是Java提供可靠的JavaMail API的原因,我们可以使用它来使用SMTP服务器发送电子邮件。
JavaMail API支持TLS和SSL身份验证来发送电子邮件。
JavaMail示例
今天,我们将学习如何使用JavaMail API通过不带身份验证,TLS和SSL身份验证的SMTP服务器发送电子邮件,以及如何发送附件以及在电子邮件正文中附加和使用图像。
对于TLS和SSL身份验证,我使用的是GMail SMTP服务器,因为它同时支持两者。
JavaMail API不是标准JDK的一部分,因此您必须从其官方(即JavaMail主页)下载它。
下载最新版本的JavaMail参考实现,并将其包含在项目构建路径中。
jar文件的名称将为javax.mail.jar。
如果您正在使用基于Maven的项目,只需在项目中添加以下依赖项。
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.5.5</version> </dependency>
发送电子邮件的Java程序包含以下步骤:
创建
javax.mail.Session对象创建
javax.mail.internet.MimeMessage对象时,我们必须在此对象中设置不同的属性,例如收件人电子邮件地址,电子邮件主题,回复电子邮件,电子邮件正文,附件等。使用
javax.mail.Transport发送电子邮件。
创建会话的逻辑因SMTP服务器的类型而异,例如,如果SMTP服务器不需要任何身份验证,我们可以创建具有一些简单属性的Session对象,而如果它需要TLS或者SSL身份验证,则创建逻辑将有所不同。
因此,我将创建一个包含一些实用程序方法的实用程序类来发送电子邮件,然后将该实用程序方法用于不同的SMTP服务器。
JavaMail示例程序
我们的EmailUtil类只有一个发送电子邮件的方法,如下所示,它需要javax.mail.Session和一些其他必填字段作为参数。
为简单起见,一些参数是硬编码的,但是您可以扩展此方法以传递它们或者从某些配置文件中读取它。
package com.theitroad.mail;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class EmailUtil {
/**
* Utility method to send simple HTML email
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendEmail(Session session, String toEmail, String subject, String body){
try
{
MimeMessage msg = new MimeMessage(session);
//set message headers
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("[email protected]", false));
msg.setSubject(subject, "UTF-8");
msg.setText(body, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
System.out.println("Message is ready");
Transport.send(msg);
System.out.println("EMail Sent Successfully!!");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
请注意,我在MimeMessage中设置了一些标头属性,电子邮件客户端使用它们来正确呈现和显示电子邮件。
该程序的其余部分很简单并且容易理解。
现在,让我们创建程序以发送未经身份验证的电子邮件。
使用SMTP无需验证即可使用SMTP发送Java邮件
package com.theitroad.mail;
import java.util.Properties;
import javax.mail.Session;
public class SimpleEmail {
public static void main(String[] args) {
System.out.println("SimpleEmail Start");
String smtpHostServer = "smtp.example.com";
String emailID = "[email protected]";
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHostServer);
Session session = Session.getInstance(props, null);
EmailUtil.sendEmail(session, emailID,"SimpleEmail Testing Subject", "SimpleEmail Testing Body");
}
}
请注意,我正在使用Session.getInstance()通过传递Properties对象来获取Session对象。
我们需要使用SMTP服务器主机设置mail.smtp.host属性。
如果SMTP服务器不在默认端口(25)上运行,则还需要设置mail.smtp.port属性。
只需使用您的无身份验证SMTP服务器并通过将收件人电子邮件ID设置为您自己的电子邮件ID来运行该程序,您将很快收到该电子邮件。
该程序易于理解并且运行良好,但是在现实生活中,大多数SMTP服务器都使用某种身份验证,例如TLS或者SSL身份验证。
现在,我们将看到如何为这些身份验证协议创建Session对象。
使用TLS身份验证以Java SMTP发送电子邮件
package com.theitroad.mail;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
public class TLSEmail {
/**
Outgoing Mail (SMTP) Server
requires TLS or SSL: smtp.gmail.com (use authentication)
Use Authentication: Yes
Port for TLS/STARTTLS: 587
*/
public static void main(String[] args) {
final String fromEmail = "[email protected]"; //requires valid gmail id
final String password = "mypassword"; //correct password for gmail id
final String toEmail = "[email protected]"; //can be any email id
System.out.println("TLSEmail Start");
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
props.put("mail.smtp.port", "587"); //TLS Port
props.put("mail.smtp.auth", "true"); //enable authentication
props.put("mail.smtp.starttls.enable", "true"); //enable STARTTLS
//create Authenticator object to pass in Session.getInstance argument
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, password);
}
};
Session session = Session.getInstance(props, auth);
EmailUtil.sendEmail(session, toEmail,"TLSEmail Testing Subject", "TLSEmail Testing Body");
}
}
由于我使用的是所有人都可以访问的GMail SMTP服务器,因此您可以在上述程序中设置正确的变量并自己运行。
具有SSL身份验证的Java SMTP示例
package com.theitroad.mail;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
public class SSLEmail {
/**
Outgoing Mail (SMTP) Server
requires TLS or SSL: smtp.gmail.com (use authentication)
Use Authentication: Yes
Port for SSL: 465
*/
public static void main(String[] args) {
final String fromEmail = "[email protected]"; //requires valid gmail id
final String password = "mypassword"; //correct password for gmail id
final String toEmail = "[email protected]"; //can be any email id
System.out.println("SSLEmail Start");
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
props.put("mail.smtp.port", "465"); //SMTP Port
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, password);
}
};
Session session = Session.getDefaultInstance(props, auth);
System.out.println("Session created");
EmailUtil.sendEmail(session, toEmail,"SSLEmail Testing Subject", "SSLEmail Testing Body");
EmailUtil.sendAttachmentEmail(session, toEmail,"SSLEmail Testing Subject with Attachment", "SSLEmail Testing Body with Attachment");
EmailUtil.sendImageEmail(session, toEmail,"SSLEmail Testing Subject with Image", "SSLEmail Testing Body with Image");
}
}
该程序与TLS身份验证几乎相同,只是某些属性不同。
如您所见,我正在从EmailUtil类调用一些其他方法来在电子邮件中发送附件和图像,但我尚未定义它们。
实际上,我让它们稍后显示,并在本教程开始时保持简单。
JavaMail示例–使用Java发送带有附件的邮件
要发送文件作为附件,我们需要创建一个对象javax.mail.internet.MimeBodyPart和javax.mail.internet.MimeMultipart。
首先在电子邮件中添加文本消息的正文部分,然后使用FileDataSource将文件附加到多部分正文的第二部分中。
该方法如下所示。
/**
* Utility method to send email with attachment
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendAttachmentEmail(Session session, String toEmail, String subject, String body){
try{
MimeMessage msg = new MimeMessage(session);
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("[email protected]", false));
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
//Create the message body part
BodyPart messageBodyPart = new MimeBodyPart();
//Fill the message
messageBodyPart.setText(body);
//Create a multipart message for attachment
Multipart multipart = new MimeMultipart();
//Set text message part
multipart.addBodyPart(messageBodyPart);
//Second part is attachment
messageBodyPart = new MimeBodyPart();
String filename = "abc.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
//Send the complete message parts
msg.setContent(multipart);
//Send message
Transport.send(msg);
System.out.println("EMail Sent Successfully with attachment!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
该程序乍一看可能看起来很复杂,但很简单,只需为短信创建一个正文部分,为附件创建另一个正文部分,然后将其添加到多部分中。
您也可以扩展此方法以附加多个文件。
JavaMail示例–使用Java发送带有图片的邮件
由于我们可以创建HTML正文消息,因此,如果图像文件位于某个服务器位置,则可以使用img元素在消息中显示它们。
但是有时我们想将图像附加到电子邮件中,然后在电子邮件正文中使用它。
您一定已经看过这么多带有图像附件的电子邮件,并且这些电子邮件也在电子邮件中使用。
诀窍是像其他任何附件一样附加图像文件,然后设置图像文件的Content-ID标头,然后在电子邮件正文中使用与<img src ='cid:image_id'>相同的内容ID。
/**
* Utility method to send image in email body
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendImageEmail(Session session, String toEmail, String subject, String body){
try{
MimeMessage msg = new MimeMessage(session);
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("[email protected]", false));
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
//Create the message body part
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
//Create a multipart message for attachment
Multipart multipart = new MimeMultipart();
//Set text message part
multipart.addBodyPart(messageBodyPart);
//Second part is image attachment
messageBodyPart = new MimeBodyPart();
String filename = "image.png";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
//Trick is to add the content-id header here
messageBodyPart.setHeader("Content-ID", "image_id");
multipart.addBodyPart(messageBodyPart);
//third part for displaying image in the email body
messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent("<h1>Attached Image</h1>" +
"<img src='cid:image_id'>", "text/html");
multipart.addBodyPart(messageBodyPart);
//Set the multipart message to the email message
msg.setContent(multipart);
//Send message
Transport.send(msg);
System.out.println("EMail Sent Successfully with image!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
JavaMail API故障排除技巧
当您的系统无法解析SMTP服务器的IP地址时,可能会出现java.net.UnknownHostException异常,这可能是错误的或者无法从网络访问。
例如,GMail SMTP服务器是smtp.gmail.com,如果我使用smtp.google.com,则会收到此异常。
如果主机名正确,请尝试通过命令行ping服务器,以确保可以从系统访问该服务器。如果您的程序停留在Transport send()方法调用中,请检查SMTP端口是否正确。
如果正确,请使用telnet验证它是否可以从您的计算机访问,您将获得如下所示的输出。

