1、springboot集成mail
首先springboot项目先要集成相应的jar包:
<!--邮件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置文件properties中的邮件配置信息:
#邮件
#POP3服务器: pop.163.com
#SMTP服务器: smtp.163.com
#IMAP服务器: imap.163.com
spring.mail.host=smtp.163.com
spring.mail.username=136XXX8276@163.com
spring.mail.password=GESZXXXXXXXQDZ
#465或者994
spring.mail.properties.mail.smtp.port=465
spring.mail.properties.mail.smtp.ssl.enable=true
#mail发送中文设置为UTF-8
spring.mail.default-encoding=UTF-8
#spring.mail.from不支持中文,需要中文,看mail.properties
email.from.name=XXXX
接下来就可以写邮件工具类了:(其中包括发送人和密送人,也可进行附件发送)
package com.chinapost.ssc.face.util;
import com.chinapost.ssc.face.handler.BaseException;
import com.chinapost.ssc.sdk.sign.StringUtils;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
/**
* @author lusong
* @version 1.0
* @date 2020/9/7 9:16
*/
@Component
public class MailUtils {
@Value("${spring.mail.default-encoding}")
private String defaultEncoding;
/**
* Spring Boot 提供了一个发送邮件的简单抽象,使用的是下面这个接口,这里直接注入即可使用
*/
@Autowired
private JavaMailSender javaMailSender;
/**
* 发送邮件的模板引擎
*/
@Autowired
private FreeMarkerConfigurer configurer;
@Value("${spring.mail.username}")
private String username;
@Value("${email.from.name}")
private String emailFromName;
/**
* 发送邮件
* @author lusong
* @param subject String 邮件主题
* @param content String 邮件内容(可html)
* @param toEmails String[] 接收人邮箱
* @param copyEmails String[] 抄送人邮箱
* @param secretEmails String[] 密送人邮箱,就是发送人和抄送人那里都不显示该收件人,但能收到邮件。
* @param fileObjs 附件(非必须)
* @throws MessagingException
*/
public void send(String subject, String content, String[] toEmails,
String[] copyEmails, String[] secretEmails,
Object... fileObjs) throws Exception {
//附件处理需要进行二进制传输
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, defaultEncoding);
//设置发件人
// log.info("emailFromName = " + emailFromName);
//log.info("from = " + from);
mimeMessageHelper.setFrom(emailFromName + "<"+ username + ">");
//设置邮件的主题
if(!StringUtils.isEmpty(subject)){
mimeMessageHelper.setSubject(subject);
}
//设置邮件的收件人
if(toEmails == null || toEmails.length <= 0){
throw new BaseException(ExceptionUtils.generalInfo("01",false,"收件人地址不可为空!"));
}
if(fileObjs != null && fileObjs.length > 0) {
handleAttachments(mimeMessageHelper, fileObjs);
}else{
if(StringUtils.isEmpty(content)){
throw new BaseException(ExceptionUtils.generalInfo("02",false,"邮件内容不可为空!"));
}
}
if(!StringUtils.isEmpty(content)){
//设置邮件的内容,区别是否是HTML邮件
mimeMessageHelper.setText(content, true);//所有都以html格式发送
}else{
mimeMessageHelper.setText("", false);
}
mimeMessageHelper.setTo(toEmails);
if(copyEmails != null && copyEmails.length > 0) {
//设置邮件的抄送人
mimeMessageHelper.setCc(copyEmails);
}
if(secretEmails != null && secretEmails.length > 0) {
//设置邮件的密送人
mimeMessageHelper.setBcc(secretEmails);
}
javaMailSender.send(mimeMessage);
}
/**
* 处理附件
* @author lusong
* @param mimeMessageHelper
* @param fileObjs 附件集合
*/
private void handleAttachments(MimeMessageHelper mimeMessageHelper,
Object... fileObjs) throws Exception{
//判断是否需要处理邮件的附件
if(fileObjs != null && fileObjs.length > 0) {
FileSystemResource resource;
String fileName;
for (int i = 0; i < fileObjs.length; i++) {
Object object = fileObjs[i];
//根据获取到的不同的邮件内容,转化成相应的File对象,进行传输
if(object instanceof File){
File file = (File)object;
resource = new FileSystemResource(file);
}else if (object instanceof String){
resource = new FileSystemResource(new File(String.valueOf(object)));
}else if(object instanceof MultipartFile){
File file = transferToFile((MultipartFile) object);
resource = new FileSystemResource(file);
}else{
throw new BaseException(ExceptionUtils.generalInfo("03",false,"附件格式不正确!"));
}
//判断该资源是否存在,当不存在时仅仅会打印一条警告日志,不会中断处理程序。
// 也就是说在附件出现异常的情况下,邮件是可以正常发送的,所以请fileObjs确定你发送的邮件附件在本机存在
if (!resource.exists()) {
throw new BaseException(ExceptionUtils.generalInfo("04",false,"邮件需要发送的附件不存在。"));
}
//获取资源的名称
fileName = resource.getFilename();
mimeMessageHelper.addAttachment(fileName, resource);
}
}
}
/**
* MultipartFile转File
* @author lusong
* @param multipartFile
* @return
*/
private File transferToFile(MultipartFile multipartFile) throws Exception {
// 选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
String originalFilename = multipartFile.getOriginalFilename();
String[] filename = originalFilename.split("\\.");
File file=File.createTempFile(filename[0], "."+filename[1]);
multipartFile.transferTo(file);
file.deleteOnExit();
return file;
}
}
2、配合Freemarker模版发送模版邮件
1的基础上添加jar包:
<!--邮件模版-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
添加配置文件信息:
#邮件模版
spring.freemarker.charset=UTF-8
spring.freemarker.suffix=.ftl
spring.freemarker.content-type=text/html; charset=utf-8
#springCloud项目中的子模块,编译完成后模版编译后的存储位置如下,如果是单纯的springboot项目则为:classpath:/templates/
spring.freemarker.template-loader-path=classpath:/BOOT-INF/classes/templates/
spring.mvc.static-path-pattern=/static/**
工具类中再次添加模版匹配方法:(根据模版文件名称进行内容融合)
/**
* 将邮件内容与模版融合
* @param templateName 模版名称,例:123.ftl
* @param map 邮件动态内容
* @return
* @throws Exception
*/
public String handleTemplate(String templateName, Map<String,Object> map) throws Exception {
Map<String, Object> model = new HashMap<>();
model.put("params", map);
Template template = configurer.getConfiguration().getTemplate(templateName);
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
return text;
}
3、编写测试类测试:
参数信息类:MailVo
package com.chinapost.ssc.face.controller.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
/**
* @author lusong
* @version 1.0
* @date 2020/9/8 11:31
*/
@Data
@ToString
public class MailVo {
@ApiModelProperty(value = "邮件标题", example = "(无标题)", required = false)
private String subject = "(无标题)";
@ApiModelProperty(value = "模版编号", example = "01", required = false)
private String code;
@ApiModelProperty(value = "邮件内容", example = "{\"code\":\"00\",\"success\":true,\"message\":\"邮件发送成功\"}", required = false)
private String mailMessage;
@ApiModelProperty(value = "收件人", required = true)
private String[] toEmails;
@ApiModelProperty(value = "抄送人", required = false)
private String[] copyEmails;
@ApiModelProperty(value = "密送人", required = false)
private String[] secretEmails;
@ApiModelProperty(value = "附件", required = false)
private Object[] fileObjs;
}
Controller:
package com.chinapost.ssc.face.controller;
import com.chinapost.ssc.common.service.annotation.Open;
import com.chinapost.ssc.face.controller.param.MailVo;
import com.chinapost.ssc.face.service.MailService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* @author lusong
* @version 1.0
* @date 2020/9/4 18:03
*/
@Log4j2
@RestController
@RequestMapping("/mail")
public class SendMailController {
@Autowired
private MailService mailService;
/**
* 发送邮件(可携带附件)
* @author lusong
* @param mailVo String 邮件信息
* @return
* @throws Exception
*/
@Open("mail.sendMail")
@ApiOperation(httpMethod = "POST", value = "邮件通知", produces = MediaType.MULTIPART_FORM_DATA_VALUE)
@PostMapping("/sendMail")
public Object sendMail(MailVo mailVo) throws Exception {
mailService.send(mailVo);
Map<String,Object> result = new HashMap<>();
result.put("code","00");
result.put("success",true);
result.put("message","邮件发送成功。");
return result;
}
}
测试service接口:
package com.chinapost.ssc.face.service;
import com.chinapost.ssc.face.controller.param.MailVo;
import javax.mail.MessagingException;
/**
* @author lusong
* @version 1.0
* @date 2020/9/7 16:44
*/
public interface MailService {
/**
* 发送邮件(可携带附件)
* @author lusong
* @param mailVo String 邮件内容
*/
void send(MailVo mailVo) throws Exception;
}
测试service实现类:
package com.chinapost.ssc.face.service.impl;
import com.alibaba.fastjson.JSON;
import com.chinapost.ssc.face.controller.param.MailVo;
import com.chinapost.ssc.face.enums.TemplatesEnum;
import com.chinapost.ssc.face.handler.BaseException;
import com.chinapost.ssc.face.service.MailService;
import com.chinapost.ssc.face.util.ExceptionUtils;
import com.chinapost.ssc.face.util.MailUtils;
import com.chinapost.ssc.sdk.sign.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import java.util.Map;
/**
* @author lusong
* @version 1.0
* @date 2020/9/8 10:31
*/
@Log4j2
@Service(value = "mailService")
public class MailServiceImpl implements MailService {
@Autowired
private MailUtils mailUtils;
@Override
public void send(MailVo mailVo) throws Exception {
if(!StringUtils.isEmpty(mailVo.getCode()) && !StringUtils.isEmpty(mailVo.getMailMessage())){
String templateName = TemplatesEnum.getTemplateName(mailVo.getCode());
Map mailMessage = JSON.parseObject(mailVo.getMailMessage(), Map.class);
String content = mailUtils.handleTemplate(templateName, mailMessage);
mailVo.setMailMessage(content);
}
mailUtils.send(mailVo.getSubject(), mailVo.getMailMessage(), mailVo.getToEmails(), mailVo.getCopyEmails(), mailVo.getSecretEmails(), mailVo.getFileObjs());
}
}
postman测试实例图片:
查看邮箱接收情况: