Comprehensive Guide to Sending Emails with Spring Boot JavaMailSender (SMTP, IMAP, POP3)
This tutorial explains the fundamentals of SMTP, IMAP, and POP3 protocols, demonstrates how to use Spring's JavaMailSender and JavaMailSenderImpl for simple and complex email sending, provides step‑by‑step project setup, configuration, code examples, a Thymeleaf UI, testing instructions, and a detailed list of common mail server error codes.
Basic Knowledge
SMTP (Simple Mail Transfer Protocol) defines how mail is transferred between servers and requires authentication to prevent spam. IMAP (Internet Message Access Protocol) allows bidirectional communication with the mail server, while POP3 (Post Office Protocol 3) typically downloads mail for offline use.
IMAP differs from POP3 in that actions such as reading or flagging messages are synchronized back to the server, whereas POP3 operations affect only the client.
Advanced Knowledge
Spring provides JavaMailSender and its implementation JavaMailSenderImpl as the primary tools for sending emails in Java back‑end applications.
Sending Email with JavaMailSenderImpl
Inject JavaMailSenderImpl and use SimpleMailMessage for plain text emails or MimeMessageHelper for complex messages with attachments. Example:
@Autowired
private JavaMailSenderImpl mailSender;
public void sendMail() throws MessagingException {
// Simple email
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setFrom("[email protected]");
simpleMailMessage.setTo("[email protected]");
simpleMailMessage.setSubject("Happy New Year");
simpleMailMessage.setText("新年快乐!");
mailSender.send(simpleMailMessage);
// Complex email with attachment
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom("[email protected]");
messageHelper.setTo("[email protected]");
messageHelper.setSubject("Happy New Year");
messageHelper.setText("新年快乐!");
messageHelper.addInline("doge.gif", new File("xx/xx/doge.gif"));
messageHelper.addAttachment("work.docx", new File("xx/xx/work.docx"));
mailSender.send(mimeMessage);
}Why JavaMailSenderImpl Works Out‑of‑the‑Box
Spring Boot auto‑configures a MailSenderPropertiesConfiguration class that creates a JavaMailSenderImpl bean using properties defined in MailProperties (host, port, username, password, protocol, etc.).
@Configuration
@ConditionalOnProperty(prefix = "spring.mail", name = "host")
class MailSenderPropertiesConfiguration {
private final MailProperties properties;
MailSenderPropertiesConfiguration(MailProperties properties) { this.properties = properties; }
@Bean
@ConditionalOnMissingBean
public JavaMailSenderImpl mailSender() {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
applyProperties(sender);
return sender;
}
}
@ConfigurationProperties(prefix = "spring.mail")
public class MailProperties {
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private String host;
private Integer port;
private String username;
private String password;
private String protocol = "smtp";
private Charset defaultEncoding = DEFAULT_CHARSET;
private Map
properties = new HashMap<>();
}Usage Tutorial
1. Enable Mail Service
Log in to a 163.com mailbox, enable POP3/SMTP/IMAP, and obtain an authorization code for authentication.
2. Configure the Project
Create a Spring Boot project (e.g., springboot-send-mail ) and add dependencies for web, Thymeleaf, mail, and optional webjars.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
...
</dependencies>Add mail configuration in application.yml (host, username, password, from, etc.).
spring:
mail:
host: smtp.163.com
username: socks
password: 123456
properties:
from: [email protected]
thymeleaf:
cache: false
prefix: classpath:/views/
servlet:
multipart:
max-file-size: 10MB
max-request-size: 50MB3. Define Mail Data Object
Create MailVo with fields such as id, from, to, subject, text, sentDate, cc, bcc, status, error, and attachment array.
public class MailVo {
private String id; // 邮件id
private String from; // 发件人
private String to; // 收件人,多个用逗号分隔
private String subject; // 主题
private String text; // 内容
private Date sentDate; // 发送时间
private String cc; // 抄送
private String bcc; // 密送
private String status; // 状态
private String error; // 错误信息
@JsonIgnore
private MultipartFile[] multipartFiles; // 附件
// getters & setters omitted
}4. Implement Mail Service
The MailService class validates the mail, builds a MimeMessage , sends it, and optionally saves it to a database.
@Service
public class MailService {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private JavaMailSenderImpl mailSender;
public MailVo sendMail(MailVo mailVo) {
try {
checkMail(mailVo);
sendMimeMail(mailVo);
return saveMail(mailVo);
} catch (Exception e) {
logger.error("发送邮件失败:", e);
mailVo.setStatus("fail");
mailVo.setError(e.getMessage());
return mailVo;
}
}
private void checkMail(MailVo mailVo) {
if (StringUtils.isEmpty(mailVo.getTo())) throw new RuntimeException("邮件收信人不能为空");
if (StringUtils.isEmpty(mailVo.getSubject())) throw new RuntimeException("邮件主题不能为空");
if (StringUtils.isEmpty(mailVo.getText())) throw new RuntimeException("邮件内容不能为空");
}
private void sendMimeMail(MailVo mailVo) {
try {
MimeMessageHelper helper = new MimeMessageHelper(mailSender.createMimeMessage(), true);
mailVo.setFrom(getMailSendFrom());
helper.setFrom(mailVo.getFrom());
helper.setTo(mailVo.getTo().split(","));
helper.setSubject(mailVo.getSubject());
helper.setText(mailVo.getText());
if (!StringUtils.isEmpty(mailVo.getCc())) helper.setCc(mailVo.getCc().split(","));
if (!StringUtils.isEmpty(mailVo.getBcc())) helper.setBcc(mailVo.getBcc().split(","));
if (mailVo.getMultipartFiles() != null) {
for (MultipartFile file : mailVo.getMultipartFiles()) {
helper.addAttachment(file.getOriginalFilename(), file);
}
}
if (mailVo.getSentDate() == null) mailVo.setSentDate(new Date());
helper.setSentDate(mailVo.getSentDate());
mailSender.send(helper.getMimeMessage());
mailVo.setStatus("ok");
logger.info("发送邮件成功:{}->{}", mailVo.getFrom(), mailVo.getTo());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private MailVo saveMail(MailVo mailVo) {
// 保存到数据库的逻辑(省略)
return mailVo;
}
public String getMailSendFrom() {
return mailSender.getJavaMailProperties().getProperty("from");
}
}5. Create Controller and Front‑End Page
MailController exposes a GET endpoint for the UI and a POST endpoint to receive the form data.
@RestController
public class MailController {
@Autowired
private MailService mailService;
@GetMapping("/")
public ModelAndView index() {
ModelAndView mv = new ModelAndView("mail/sendMail");
mv.addObject("from", mailService.getMailSendFrom());
return mv;
}
@PostMapping("/mail/send")
public MailVo sendMail(MailVo mailVo, MultipartFile[] files) {
mailVo.setMultipartFiles(files);
return mailService.sendMail(mailVo);
}
}The Thymeleaf template sendMail.html provides a form for sender, recipient, subject, content, and file upload, and uses jQuery AJAX to submit the data.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>发送邮件</title>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet"/>
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</head>
<body>
<div class="col-md-6" style="margin:20px;padding:20px;border:#E0E0E0 1px solid;">
<form class="form-horizontal" id="mailForm">
... (form fields for from, to, subject, text, files) ...
</form>
<script th:inline="javascript">
var appCtx = [[${#request.getContextPath()}]];
function sendMail() {
var formData = new FormData($('#mailForm')[0]);
$.ajax({
url: appCtx + '/mail/send',
type: 'POST',
data: formData,
contentType: false,
processData: false,
success: function (result) {
alert(result.status === 'ok' ? '发送成功!' : '你被Doge嘲讽了:' + result.error);
},
error: function () { alert('发送失败!'); }
});
}
function clearForm() { $('#mailForm')[0].reset(); }
</script>
</div>
</body>
</html>Testing
Run the Spring Boot application, open http://localhost:8080 , fill in the recipient address and content, and click "发送邮件". If configured correctly, the email and any attachments appear in the target mailbox.
Common Failure Codes
A list of SMTP error codes (421, 450, 451, 500, 552, 553, 554) with explanations specific to NetEase mail servers is provided to help diagnose delivery problems.
End of guide.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.