网站首页 > 知识剖析 正文
Spring Boot 邮件发送功能实现
一、功能设计
本文将实现一个完整的 Spring Boot 邮件发送系统,包含前端与后端两部分,功能如下:
- 简洁的邮件发送表单界面
- 支持 收件人、主题、内容 填写
- 支持 附件上传(多文件)
- 响应式设计,适配不同设备
- 发送状态实时反馈
- 可扩展:邮件模板、异步发送、日志记录
二、前端实现
前端使用 Bootstrap 5,包含收件人、主题、内容、附件上传等表单项,并提供 拖拽上传文件 与 发送状态提示。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Spring Boot 邮件发送系统</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background-color: #f5f8fa; padding: 20px; }
.email-card { box-shadow: 0 0 15px rgba(0, 0, 0, 0.1); border-radius: 10px; border: none; }
.card-header { background-color: #0d6efd; color: white; border-radius: 10px 10px 0 0 !important; }
.attachment-area { border: 2px dashed #ccc; border-radius: 5px; padding: 15px; text-align: center; background-color: #f8f9fa; cursor: pointer; }
.attachment-area:hover { background-color: #e9ecef; }
.btn-send { background-color: #0d6efd; border: none; padding: 10px 20px; font-weight: bold; }
.btn-send:hover { background-color: #0b5ed7; }
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card email-card">
<div class="card-header">
<h3 class="card-title mb-0">发送邮件</h3>
</div>
<div class="card-body">
<form id="emailForm" enctype="multipart/form-data">
<div class="mb-3">
<label for="to" class="form-label">收件人</label>
<input type="email" class="form-control" id="to" required multiple placeholder="多个收件人用逗号分隔">
</div>
<div class="mb-3">
<label for="subject" class="form-label">主题</label>
<input type="text" class="form-control" id="subject" required placeholder="邮件主题">
</div>
<div class="mb-3">
<label for="content" class="form-label">内容</label>
<textarea class="form-control" id="content" rows="5" required placeholder="输入邮件内容..."></textarea>
</div>
<div class="mb-3">
<label class="form-label">附件</label>
<div class="attachment-area" onclick="document.getElementById('attachments').click()">
<div class="text-muted">
<p>点击选择文件或拖拽文件到此处</p>
<small>支持多个文件</small>
</div>
</div>
<input type="file" id="attachments" multiple style="display:none" onchange="handleFileSelect(event)">
<div id="attachmentList" class="mt-2"></div>
</div>
<button type="submit" class="btn btn-primary btn-send w-100">
<span id="sendText">发送邮件</span>
<div id="loadingSpinner" class="spinner-border spinner-border-sm" role="status" style="display:none;">
<span class="visually-hidden">发送中...</span>
</div>
</button>
</form>
<div id="alertBox" class="mt-3"></div>
</div>
</div>
</div>
</div>
</div>
<script>
function handleFileSelect(event) {
const files = event.target.files;
const attachmentList = document.getElementById('attachmentList');
attachmentList.innerHTML = '';
if (files.length > 0) {
const list = document.createElement('ul');
list.className = 'list-group';
for (let i = 0; i < files.length; i++) {
const listItem = document.createElement('li');
listItem.className = 'list-group-item d-flex justify-content-between align-items-center';
listItem.innerHTML = `${files[i].name} <span class="badge bg-primary rounded-pill">${(files[i].size/1024).toFixed(1)} KB</span>`;
list.appendChild(listItem);
}
attachmentList.appendChild(list);
}
}
document.getElementById('emailForm').addEventListener('submit', function(e) {
e.preventDefault();
const sendButton = document.querySelector('button[type="submit"]');
const sendText = document.getElementById('sendText');
const spinner = document.getElementById('loadingSpinner');
sendText.textContent = '发送中...';
spinner.style.display = 'inline-block';
sendButton.disabled = true;
const formData = new FormData();
formData.append('to', document.getElementById('to').value);
formData.append('subject', document.getElementById('subject').value);
formData.append('content', document.getElementById('content').value);
const attachments = document.getElementById('attachments').files;
for (let i = 0; i < attachments.length; i++) {
formData.append('attachments', attachments[i]);
}
fetch('/api/sendEmail', { method: 'POST', body: formData })
.then(res => res.json())
.then(data => {
showAlert(data.success ? '邮件发送成功!' : '发送失败:' + data.message, data.success ? 'success' : 'danger');
if (data.success) document.getElementById('emailForm').reset();
})
.catch(err => showAlert('错误:' + err.message, 'danger'))
.finally(() => {
sendText.textContent = '发送邮件';
spinner.style.display = 'none';
sendButton.disabled = false;
});
});
function showAlert(message, type) {
document.getElementById('alertBox').innerHTML = `<div class="alert alert-${type} alert-dismissible fade show">${message}<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>`;
}
</script>
</body>
</html>
三、后端实现
1. Maven 依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
2. 配置文件 (application.yml)
spring:
mail:
host: smtp.qq.com # SMTP 服务器地址
username: your-email@qq.com
password: your-app-password # 授权码,不是邮箱密码
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
3. 控制器 (EmailController.java)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.mail.internet.MimeMessage;
import java.util.HashMap;
import java.util.Map;
@RestController
public class EmailController {
@Autowired
private JavaMailSender mailSender;
@PostMapping("/api/sendEmail")
public Map<String, Object> sendEmail(
@RequestParam String to,
@RequestParam String subject,
@RequestParam String content,
@RequestParam(required = false) MultipartFile[] attachments) {
Map<String, Object> resp = new HashMap<>();
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(to.split("\\s*,\\s*"));
helper.setSubject(subject);
helper.setText(content, true);
if (attachments != null) {
for (MultipartFile file : attachments) {
if (!file.isEmpty()) {
helper.addAttachment(file.getOriginalFilename(),
new ByteArrayResource(file.getBytes()));
}
}
}
mailSender.send(message);
resp.put("success", true);
} catch (Exception e) {
resp.put("success", false);
resp.put("message", e.getMessage());
}
return resp;
}
}
4. 启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class EmailApplication {
public static void main(String[] args) {
SpringApplication.run(EmailApplication.class, args);
}
}
四、使用说明
- 修改 application.yml 中的邮箱配置。
- 启动项目,访问 http://localhost:8080。
- 填写收件人、主题、正文,上传附件。
- 点击 发送 按钮即可完成邮件发送。
五、注意事项
- 必须在邮箱中开启 SMTP 服务,并使用授权码。
- 常见邮箱配置:
- QQ 邮箱:smtp.qq.com,端口 465/587
- 163 邮箱:smtp.163.com
- Gmail:smtp.gmail.com
- 上传文件大小受 spring.servlet.multipart.max-file-size 限制。
六、扩展与优化
- 安全性
- 使用环境变量存储邮箱账号密码,而不是写死在配置文件。
- 异步发送
- 使用 @Async 或消息队列,避免阻塞主线程:
@Async public void sendMailAsync(...) { ... }
- 模板美化
- 使用 Thymeleaf 渲染 HTML 邮件模板,发送更美观的通知。
- 发送记录
- 在数据库中记录邮件发送历史,方便查询与追踪。
以上就是一个完整的 Spring Boot 邮件发送功能实现,前后端一体化,可直接运行,也便于扩展成企业级邮件通知系统。
猜你喜欢
- 2025-09-13 Global Postal Services Suspend U.S. Shipments as End of Tariff Loophole Sparks Shipping Chaos
- 2025-09-13 看完之后你还敢随便卖电脑吗_现在卖电脑还能赚钱吗
- 2025-09-13 西门子 PLC 编程中的常用指令详解基础篇
- 2025-09-13 Rust 中的特性(Trait):从基础到高级
- 2025-09-13 flask编写文件上传小应用_flask上传文件接口
- 2025-09-13 102743-85-1,生物胞素酰肼 :标记糖蛋白的方法(基于氧化醛基)
- 2025-09-13 2016年全球最具创意的26款饮料出炉!
- 2025-09-13 可能高级前端开发者都不会使用的冷门HTML标签
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)