Servlet – 发送电子邮件
电子邮件被认为是互联网上最安全、可靠、快速和最便宜的官方通信方式。这就是每秒发送近 270 万封电子邮件的原因。因此,您的 Web 应用程序可能需要电子邮件服务来满足许多需求,例如 - 通信、多因素身份验证等。在 servlet 中使用邮件服务需要 - SMTP 服务器(本地/远程)和以下两个 API。
- Java邮件 API (JMA) – javax.mail.jar
- JavaBeans 激活框架 API (JAF) – activation.jar
先决条件:
- 如果您使用 Gmail SMTP 服务器,登录尝试可能会被阻止,因为
- 两步验证已开启,
- 安全性较低的应用程序访问已关闭。
- 您可以更改 google 帐户设置或使用 Google 登录/Google 生成的应用程序代码。
- 了解邮件服务协议
Protocols | Description |
---|---|
SMTP | Simple Mail Transfer Protocol is used to send a message from one mail server to another. |
POP | Post Office Protocol is used to retrieve messages from a mail server. This protocol transfers all messages from the mail server to the mail client. |
IMAP | Internet Message Access Protocol is used by web-based mail services such as Gmail and Yahoo. This protocol allows a web browser to read messages that are stored on the mail server. |
MIME | The Multipurpose Internet Mail Extension type specifies the type of content that can be sent as a message or attachment. |
了解电子邮件的工作原理
关联Java Mail API 的步骤:
- 下载 javax.mail.jar 文件。
- 将 javax.mail.jar 文件复制到应用程序的 WEB-INF\lib 目录。
- 将 javax.mail.jar 文件添加到应用程序的类路径中。
关联 JavaBeans Activation Framework API 的步骤:
- 下载 ZIP 文件并解压缩文件。
- 将activation.jar 文件复制到应用程序的WEB-INF\lib 目录。
- 将activation.jar 文件添加到应用程序的类路径中。
Note: The JavaBeans Activation Framework API is included with Java SE 6. As a result, if you’re using Java SE 6 or later, you don’t need to install this API.
Web 应用程序(Servlet)结构:
1] web.xml (配置)
XML
Email
mail.Servlet.Email
Email
/Email
30
HTML
GeeksforGeeks
Java
package mail.Servlet;
import static mail.Servlet.Mail.sendMail;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Email extends HttpServlet {
protected void
processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String id, sender, receiver, password, subject,
message;
// check if directed url
String action = request.getParameter("action");
String url = "/index.html";
if (action == null) {
// directed to email interface
action = "join";
}
if (action.equals("join")) {
url = "/index.html";
}
if (action.equals("add")) {
// retrieve the entered credentials
id = request.getParameter("id");
sender = request.getParameter("emailSender");
receiver
= request.getParameter("emailReceiver");
password = request.getParameter("password");
subject = request.getParameter("subject");
message = request.getParameter("message");
// get and set String value of email status
request.setAttribute(
"message",
sendMail(id, receiver, sender, subject,
message, true, password));
// directed to page showing the status of email
url = "/confirmation.jsp";
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
// Returns a short description of the servlet.
// @return a String containing servlet description
@Override public String getServletInfo()
{
return "Short description";
}
}
Java
package mail.Servlet;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class Mail {
public static String
sendMail(String id, String to, String from,
String subject, String body, boolean content,
String password)
{
String status = null;
try {
// acquire a secure SMTPs session
Properties pros = new Properties();
pros.put("mail.transport.protocol", "smtps");
pros.put("mail.smtps.host", "smtp.gmail.com");
pros.put("mail.smtps.port", 465);
pros.put("mail.smtps.auth", "true");
pros.put("mail.smtps.quitwait", "false");
Session session
= Session.getDefaultInstance(pros);
session.setDebug(true);
// Wrap a message in session
Message message = new MimeMessage(session);
message.setSubject(subject);
if (content) {
message.setContent(body, "text/html");
}
else {
message.setText(body);
}
// specify E-mail address of Sender and Receiver
Address sender = new InternetAddress(from, id);
Address receiver = new InternetAddress(to);
message.setFrom(sender);
message.setRecipient(Message.RecipientType.TO,
receiver);
// sending an E-mail
try (Transport tt = session.getTransport()) {
// acqruiring a connection to remote server
tt.connect(from, password);
tt.sendMessage(message,
message.getAllRecipients());
status = "E-Mail Sent Successfully";
}
}
catch (MessagingException e) {
status = e.toString();
}
catch (UnsupportedEncodingException e) {
status = e.toString();
}
// return the status of email
return status;
}
}
HTML
<%@page contentType="text/html" pageEncoding="UTF-8"%>
GeeksforGeeks
Status of E-Mail :
${requestScope.message}
2] index.html (输入详细信息)
HTML
GeeksforGeeks
输出:
3] 电子邮件。 Java (处理细节的Servlet)
Java
package mail.Servlet;
import static mail.Servlet.Mail.sendMail;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Email extends HttpServlet {
protected void
processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String id, sender, receiver, password, subject,
message;
// check if directed url
String action = request.getParameter("action");
String url = "/index.html";
if (action == null) {
// directed to email interface
action = "join";
}
if (action.equals("join")) {
url = "/index.html";
}
if (action.equals("add")) {
// retrieve the entered credentials
id = request.getParameter("id");
sender = request.getParameter("emailSender");
receiver
= request.getParameter("emailReceiver");
password = request.getParameter("password");
subject = request.getParameter("subject");
message = request.getParameter("message");
// get and set String value of email status
request.setAttribute(
"message",
sendMail(id, receiver, sender, subject,
message, true, password));
// directed to page showing the status of email
url = "/confirmation.jsp";
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
// Returns a short description of the servlet.
// @return a String containing servlet description
@Override public String getServletInfo()
{
return "Short description";
}
}
4] 邮件。 Java (用于创建和发送邮件的帮助类)
基本课程:
Packages Description java.util javax.mailContains Properties class that’s used to set the properties for the email session. Contains Session, Message, Address, Transport, MessagingException classes to send messages. javax.mail.internet Contains MimeMessage and InternetAddress classes to send Email messages over the internet.
创建和发送电子邮件:
创建邮件会话:
- 您必须创建一个邮件会话才能创建和发送电子邮件消息。
- 在创建会话之前,您需要使用会话发送或接收邮件所需的 put(key, value) 方法创建一个包含属性(键值对)的 Properties 对象。
- 您至少需要指定 SMTP 主机属性——使用 'localhost' 关键字来指定与 web 应用程序在同一服务器上运行的 SMTP 服务器。如果您使用远程 SMTP 服务器(例如 Gmail 服务器),请使用 SMTPS 协议(安全连接和身份验证)。
- 您也可以使用其他属性来配置邮件会话。
- 通过将 Properties 对象包装到 Session 类的 getDefaultInstance(Properties Object) 方法中来获取 Session 对象。
Common Properties | Description |
---|---|
mail.transport.protocol | Specifies the protocol that’s used for the session. |
mail.smtp.host | Specifies the host computer for the SMTP server. |
mail.smtp.port | Specifies the port that the SMTP server is using. |
mail.smtp.auth | Specifies whether authentication is required to log in to the SMTP server. |
mail.smtp.quitwait | Set to false to prevent an SSLException on an attempt to connect to the Gmail SMTP server. |
// local SMTP server - Default
Properties props = new Properties();
props.put("mail.smtp.host", "localhost");
Session session = Session.getDefaultInstance(props);
// local SMTP server - Configure
Properties props = new Properties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", "localhost");
props.put("mail.smtp.port", 25);
Session session = Session.getDefaultInstance(props);
session.setDebug(true);
// remote SMTP server
Properties props = new Properties();
props.put("mail.transport.protocol", "smtps");
props.put("mail.smtps.host", "smtp.gmail.com");
props.put("mail.smtps.port", 465);
props.put("mail.smtps.auth","true");
props.put("mail.smtps.quitwait","false");
Session session = Session.getDefaultInstance(props);
session.setDebug(true);
创建消息:
- 要创建消息,需要将 Session 对象传递给 MimeMessage 类的构造函数,以创建 MimeMessage 对象。
- 您可以设置邮件的主题、正文和地址。
- 如果正文不是纯文本,请使用 setContent() 方法更改消息的 MIME 类型。
Message message = new MimeMessage(session);
message.setSubject("Test");
// automatically sets to text/plain
message.setText("Test Successful");
message.setContent("Test Successful", "text/html");
Note: All of the Message methods used above throws javax.mail.MessagingException.
// add attachments within email
// create 1'st part of body
BodyPart bodyPart = new MimeBodyPart();
bodyPart.setText("Body Message");
Multipart multiPart = new MimeMultipart();
// wrap up 1'st part
multiPart.addBodyPart(bodyPart);
// create 2'nd part of body
bodyPart = new MimeBodyPart();
DataSource source = new FileDataSource("Filename.txt");
bodyPart.setDataHandler(new DataHandler(source));
bodyPart.setFileName("Filename.txt");
// wrap up 2'nd part.
multiPart.addBodyPart(bodyPart);
// adds wrapped parts in message
message.setContent(multiPart);
处理消息:
- 创建 InternetAddress 的对象(地址类的子类)。
- 第一个参数指定电子邮件地址。
- 您可以添加第二个参数来关联要显示的 ID 或电子邮件地址。
- 设置 FROM 地址。使用 MimeMessage 对象的 setFrom(Address add) 方法。
- 要设置 TO、CC(抄送)、BCC(密件抄送)地址,请使用 MimeMessage 对象的 setRecipient(Type type, Address add) 方法。
- 对于多个收件人,您可以使用 MimeMessage 对象的 setRecipients(Type type, Address[] add) 方法。
// set sender
Address fromAdd = new InternetAddress("from@gmail.com", "from ID");
message.setFrom(fromAdd);
// set recipient
Address toAdd = new InternetAddress("to@gmail.com");
message.setRecipient(Message.RecipientType.TO, toAdd);
message.setRecipient(Message.RecipientType.CC, toAdd);
message.setRecipient(Message.RecipientType.BCC, toAdd);
// set recipients
message.setRecipients(Message.RecipientType.TO, new Address[]{new InternetAddress("to1@gmail.com"),new InternetAddress("to2@gmail.com")});
// add recipients
Address toAdd1 = new InternetAddress("to@gmail.com");
message.addRecipient(Message.RecipientType.TO, toAdd1);
Note: When you send a carbon copy, the CC addresses appear in the message. When you send a blind carbon copy, the BCC address doesn’t appear in the message. If you use the two-argument constructor of InternetAddress, it throws the java.io.UnsupportedEncoding Exception.
发送消息:
如果 SMTP 不需要身份验证,则可以使用 Transport 类的静态 send(Message msg) 方法发送消息。
Transport.send(message);
- 如果 SMTP 需要身份验证,您可以使用会话对象的 getTransport() 方法。
- 然后您可以使用连接方法 - public void connect(String user, String password) 来指定凭据(用户名、密码)以连接到服务器。
- 使用 abstract void sendMessage(Message msg, Address[] addresses) 方法发送消息。
- 如果不使用 try-with-resources 块,则需要使用 close() 方法关闭连接。
Transport transport = session.getTransport();
transport.connect("email-id", "password");
transport.sendMessage("message", message.getAllRecipients());
transport.close();
Note: If the SMTP host is incorrect, the – static void send(Message msg) method throws SendFailedException.
Java
package mail.Servlet;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class Mail {
public static String
sendMail(String id, String to, String from,
String subject, String body, boolean content,
String password)
{
String status = null;
try {
// acquire a secure SMTPs session
Properties pros = new Properties();
pros.put("mail.transport.protocol", "smtps");
pros.put("mail.smtps.host", "smtp.gmail.com");
pros.put("mail.smtps.port", 465);
pros.put("mail.smtps.auth", "true");
pros.put("mail.smtps.quitwait", "false");
Session session
= Session.getDefaultInstance(pros);
session.setDebug(true);
// Wrap a message in session
Message message = new MimeMessage(session);
message.setSubject(subject);
if (content) {
message.setContent(body, "text/html");
}
else {
message.setText(body);
}
// specify E-mail address of Sender and Receiver
Address sender = new InternetAddress(from, id);
Address receiver = new InternetAddress(to);
message.setFrom(sender);
message.setRecipient(Message.RecipientType.TO,
receiver);
// sending an E-mail
try (Transport tt = session.getTransport()) {
// acqruiring a connection to remote server
tt.connect(from, password);
tt.sendMessage(message,
message.getAllRecipients());
status = "E-Mail Sent Successfully";
}
}
catch (MessagingException e) {
status = e.toString();
}
catch (UnsupportedEncodingException e) {
status = e.toString();
}
// return the status of email
return status;
}
}
5]confirmation.jsp (检查邮件状态)
HTML
<%@page contentType="text/html" pageEncoding="UTF-8"%>
GeeksforGeeks
Status of E-Mail :
${requestScope.message}
输出: