1.开启邮箱服务
2.引入相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.zhao</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 发送邮件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
</dependencies>
</project>
3.application.yml添加邮箱信息
spring:
mail:
host: smtp.163.com #SMTP服务器地址
username: xxx@163.com #登陆账号
password: xxx #登陆密码(或授权码)
properties:
from: xxx@163.com #邮件发信人(即真实邮箱)
thymeleaf:
cache: false
prefix: classpath:/views/
servlet:
multipart:
max-file-size: 10MB #限制单个文件大小
max-request-size: 50MB #限制请求总量
4.添加邮件扩展类MailVo
/**
* 创建邮件扩展类
* @author zxy
*/
public class MailVo implements Serializable {
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;// 邮件附件
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Date getSentDate() {
return sentDate;
}
public void setSentDate(Date sentDate) {
this.sentDate = sentDate;
}
public String getCc() {
return cc;
}
public void setCc(String cc) {
this.cc = cc;
}
public String getBcc() {
return bcc;
}
public void setBcc(String bcc) {
this.bcc = bcc;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public MultipartFile[] getMultipartFiles() {
return multipartFiles;
}
public void setMultipartFiles(MultipartFile[] multipartFiles) {
this.multipartFiles = multipartFiles;
}
5.邮件接口MailService
public interface MailService {
MailVo sendMail(MailVo mailVo);
String getMailSendFrom();
}
6.邮件实现类MailServiceImpl
public class MailServiceImpl implements MailService {
private Logger logger = LoggerFactory.getLogger(getClass());// 提供日志类
@Autowired
private JavaMailSenderImpl mailSender;
/**
* 发送邮件
*
* @param mailVo
* @return
*/
@Override
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;
}
}
/**
* 保存邮件
*
* @param mailVo
* @return
*/
private MailVo saveMail(MailVo mailVo) {
// TODO
return mailVo;
}
/**
* 构建复杂邮件信息类
*
* @param mailVo
*/
private void sendMimeMail(MailVo mailVo) {
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(mailSender.createMimeMessage(), true);// true表示支持复杂类型
mailVo.setFrom(getMailSendFrom());// 邮件发信人从配置项读取
messageHelper.setFrom(mailVo.getFrom());// 邮件发信人
messageHelper.setTo(mailVo.getTo().split(","));// 邮件收信人
messageHelper.setSubject(mailVo.getSubject());// 邮件主题
messageHelper.setText(mailVo.getText());// 邮件内容
if (StringUtils.isNotEmpty(mailVo.getCc())) {// 抄送
messageHelper.setCc(mailVo.getCc().split(","));
}
if (!StringUtils.isEmpty(mailVo.getBcc())) {// 密送
messageHelper.setCc(mailVo.getBcc().split(","));
}
if (mailVo.getMultipartFiles() != null) {// 添加邮件附件
for (MultipartFile multipartFile : mailVo.getMultipartFiles()) {
messageHelper.addAttachment(multipartFile.getOriginalFilename(), multipartFile);
}
}
if (mailVo.getSentDate() != null && !("".equals(mailVo.getSentDate().toString()))) {// 发送时间
mailVo.setSentDate(new Date());
messageHelper.setSentDate(mailVo.getSentDate());
}
mailSender.send(messageHelper.getMimeMessage());// 正式发送邮件
mailVo.setStatus("ok");
logger.info("发送邮件成功:{}->{}", mailVo.getFrom(), mailVo.getTo());
} catch (MessagingException e) {
e.printStackTrace();
}
}
/**
* 获取邮件发信人
*
* @return
*/
@Override
public String getMailSendFrom() {
return mailSender.getJavaMailProperties().getProperty("from");
}
/**
* 校验
*
* @param 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("邮件内容不能为空");
}
}
7.邮件web层MailController
@RestController
public class MailController {
@Autowired
private MailServiceImpl mailServiceImpl;
/**
* 发送邮件的主界面
*/
@GetMapping("/")
public ModelAndView index() {
ModelAndView mv = new ModelAndView("mail/sendMail");// 打开发送邮件的页面
mv.addObject("from", mailServiceImpl.getMailSendFrom());// 邮件发信人
return mv;
}
/**
* 发送邮件
*/
@PostMapping("/mail/send")
public MailVo sendMail(MailVo mailVo, MultipartFile[] files) {
mailVo.setMultipartFiles(files);
return mailServiceImpl.sendMail(mailVo);// 发送邮件和附件
}
8.页面sendMail.html
<!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" type="text/css" />
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:href="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</head>
<body>
<div class="col-md-6"
style="margin: 20px; padding: 20px; border: #E0E0E0 1px solid;">
<marquee behavior="alternate" onfinish="alert(12)" id="mq"
onMouseOut="this.start();$('#egg').text('嗯 真听话!');"
onMouseOver="this.stop();$('#egg').text('有本事放开我呀!');">
<h5 id="egg">祝大家新年快乐!</h5>
<img id="doge"
src="http://pics.sc.chinaz.com/Files/pic/faces/3709/7.gif" alt="">
</marquee>
<form class="form-horizontal" id="mailForm">
<div class="form-group">
<label class="col-md-2 control-label">邮件发信人:</label>
<div class="col-md-6">
<input class="form-control" id="from" name="from"
th:value="${from}" readonly="readonly">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">邮件收信人:</label>
<div class="col-md-6">
<input class="form-control" id="to" name="to" title="多个邮箱使用,隔开">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">邮件主题:</label>
<div class="col-md-6">
<input class="form-control" id="subject" name="subject">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">邮件内容:</label>
<div class="col-md-6">
<textarea class="form-control" id="text" name="text" rows="5"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">邮件附件:</label>
<div class="col-md-6">
<input class="form-control" id="files" name="files" type="file"
multiple="multiple">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">邮件操作:</label>
<div class="col-md-3">
<a class="form-control btn btn-primary" onclick="sendMail()">发送邮件</a>
</div>
<div class="col-md-3">
<a class="form-control btn btn-default" onclick="clearForm()">清空</a>
</div>
</div>
</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();
}
setInterval(function () {
var total = $('#mq').width();
var width = $('#doge').width();
var left = $('#doge').offset().left;
if (left <= width / 2 + 20) {
$('#doge').css('transform', 'rotateY(180deg)')
}
if (left >= total - width / 2 - 40) {
$('#doge').css('transform', 'rotateY(-360deg)')
}
});
</script>
</div>
</body>
</html>
9.测试