Introduction#
Today I created an automatic clock-in tool and prepared to set up an email service to report clock-in results. The email used is Yandex Mail. I encountered the error Got bad greeting from SMTP host: smtp.yandex.com, port: 465, response: [EOF], so I am recording this.
Email Preparation#
There are no specific requirements for using the email, as long as it supports SMTP.
Register Email#
Log in to Email#
After logging into the email, you may be prompted to enable SMTP.
Here is the official document provided for enabling SMTP, which also records the port number.
Enable SMTP#
In the top right corner of the email homepage, click the gear > security > Email clients >
Here I tested the connection using Outlook, and the port used is 465, attached is the successful connection screenshot.
Email Protocols#
SMTP Protocol#
SMTP is a relatively simple text-based protocol. It specifies one or more recipients for a message (which are confirmed to exist in most cases), and then the message text is transmitted. An SMTP server can be easily tested using the telnet program. The SMTP protocol that provides SSL encryption is called SMTPS, with SMTP using TCP port 25
and SMTPS using TCP port 465
.
POP3 Protocol#
POP3, which stands for "Post Office Protocol - Version 3," is a member of the TCP/IP protocol family, defined by RFC1939. This protocol is mainly used to support remote management of emails on the server using a client. The POP3 protocol that provides SSL encryption is called POP3S, with the default port for POP3 being 110
and for POP3S being 995
.
IMAP Protocol#
IMAP (Internet Mail Access Protocol), formerly known as Interactive Mail Access Protocol, is an application layer protocol. IMAP is a mail retrieval protocol developed by Stanford University in 1986. Its main function is to allow mail clients to retrieve email information from the mail server and download emails. The current authoritative definition is RFC3501. The IMAP protocol runs on top of the TCP/IP protocol and uses port 143
. The main difference from the POP3 protocol is that users do not need to download all emails; they can operate directly on the emails on the server through the client. The IMAP protocol that provides SSL encryption is called IMAP S, with the default port for POP3 being 143
and for POP3S being 993
.
Setup Steps and Simple Usage#
Mail Dependency#
build.gradle file
compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '2.3.2.RELEASE'
YML Configuration File#
server:
port: 80
logging:
level:
web: debug
spring:
mail:
default-encoding: UTF-8
host: smtp.yandex.com
username: [email protected]
password: 123456
port: 25 # SMTP protocol uses port 25
# port: 465 # SMTPS uses port 465, otherwise it will report an error.
protocol: smtp # Specify protocol
test-connection: true
properties:
mail:
smtp:
auth: true # Use
starttls: # Use SSL security protocol, must be configured as follows
enable: true
required: true
Java Code#
MailService Interface File#
public interface MailService {
/**
* Send plain text email
* @param toAddr Recipient
* @param title Title
* @param content Content
*/
void sendTextMail(String toAddr, String title, String content);
/**
* Send HTML email
* @param toAddr Recipient
* @param title Title
* @param content Content (HTML)
*/
void sendHtmlMail(String toAddr, String title, String content);
/**
* Send email with attachments
* @param toAddr Recipient
* @param title Title
* @param content Content
* @param filePath Attachment address
*/
void sendAttachmentsMail(String toAddr, String title, String content, String filePath);
/**
* Send email with static resources (images) in the text
* @param toAddr Recipient
* @param title Title
* @param content Content
* @param rscPath Resource path
* @param rscId Resource id (may have multiple images)
*/
void sendInlineResourceMail(String toAddr, String title, String content, String rscPath, String rscId);
}
MailServiceImpl File#
@Component
public class MailServiceImpl implements MailService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final JavaMailSender mailSender;
/**
* Inject constants
*/
@Value("${spring.mail.username}")
private String from;
public MailServiceImpl(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
/**
* Send plain text email
*
* @param toAddr Recipient
* @param title Title
* @param content Content
*/
@Override
public void sendTextMail(String toAddr, String title, String content) {
// Plain text email object
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(toAddr);
message.setSubject(title);
message.setText(content);
try {
mailSender.send(message);
if (logger.isInfoEnabled()) {
logger.info("Text email has been sent.");
}
} catch (Exception e) {
logger.error("An exception occurred while sending the text email!", e);
}
}
/**
* Send HTML email
*
* @param toAddr Recipient
* @param title Title
* @param content Content (HTML)
*/
@Override
public void sendHtmlMail(String toAddr, String title, String content) {
// HTML email object
MimeMessage message = mailSender.createMimeMessage();
try {
// true indicates that a multipart message needs to be created
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(toAddr);
helper.setSubject(title);
helper.setText(content, true);
mailSender.send(message);
if (logger.isInfoEnabled()) {
logger.info("HTML email sent successfully");
}
} catch (MessagingException e) {
logger.error("An exception occurred while sending the HTML email!", e);
}
}
/**
* Send email with attachments
*
* @param toAddr Recipient
* @param title Title
* @param content Content
* @param filePath Attachment address
*/
@Override
public void sendAttachmentsMail(String toAddr, String title, String content, String filePath) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(toAddr);
helper.setSubject(title);
helper.setText(content, true);
FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
helper.addAttachment(fileName, file);
mailSender.send(message);
if (logger.isInfoEnabled()) {
logger.info("Email with attachments has been sent.");
}
} catch (MessagingException e) {
logger.error("An exception occurred while sending the email with attachments!", e);
}
}
/**
* Send email with static resources (images) in the text
*
* @param toAddr Recipient
* @param title Title
* @param content Content
* @param rscPath Resource path
* @param rscId Resource id (may have multiple images)
*/
@Override
public void sendInlineResourceMail(String toAddr, String title, String content, String rscPath, String rscId) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(toAddr);
helper.setSubject(title);
helper.setText(content, true);
FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(rscId, res);
mailSender.send(message);
if (logger.isInfoEnabled()) {
logger.info("Email with embedded static resources has been sent.");
}
} catch (MessagingException e) {
logger.error("An exception occurred while sending the email with embedded static resources!", e);
}
}
}
Test Class#
@SpringBootTest
class ClockInApplicationTests {
@Autowired
MailService mailService;
@Test
void sendTextMail(){
mailService.sendTextMail("[email protected]","Unit Test","Test email sending");
}
}
Running Result#
As mentioned in the title, an exception occurred
After using the corresponding port for the protocol, the sending was successful, attached is the image.
Conclusion#
Through this practice, I feel that a lot of preparation is needed before writing code, or that my understanding of things is not comprehensive. After making a mistake, I couldn't find the abnormal information on Baidu, wondering where the error was. Previously, I successfully tested the connection using Outlook, so it should be a code issue. Later, I saw that many people used port 25 to send emails, and then searched for the port on Baidu to find that the protocol and port were inconsistent. Therefore, I believe that insufficient preparation or lack of knowledge before writing code is crucial information that I did not understand.