前言
在开发中,经常会碰到email邮件发送的场景 如发送验证码,向客户发送邮件等等。如何通过Springboot 发送email 邮件 普通文本邮件 ,HTML内容板式邮件 ,包含静态资源邮件,以及带附件邮件?
- 邮件发送需要引入spring-boot-start-mail
- SpringBoot 自动配置MailSenderAutoConfiguration
- 定义MailProperties内容,配置在application.yml中
- 自动装配JavaMailSender
- 测试邮件发送
一:邮件发送需要的配置
因为各大邮件都有其对应安全系统,不是项目中想用就可以用的,我们必须要拿到其对应的客户端授权码才行,拿到授权码,在项目中配置SMTP服务协议以及主机 配置账户 ,就可以在项目中使用各大邮件运营商进行发送邮件了
发送邮件工程
获取客户端授权码,由于国内使用163邮箱以及qq邮箱较多 所以本文中仅仅展示这两个运营商获取客户端授权码的步骤
获取163邮箱授权码
登陆163邮箱
查看勾选服务是否开启,如未开启则勾选
在未设置授权码时 点击此页面回叫你使用当前邮箱账号绑定的手机号 发送一条短信确认
发送后,确认成功后,便可自定义163邮箱的客户端授权码了
获取QQ邮箱授权码
登陆qq邮箱后,点击设置 选择 账户选项,选择开启pop3(我已经开启 所以显示关闭,然后会弹窗让你发送短信,发送即可获取授权码)
我们在拿到授权码后,就可以在我们Springboot工程中的配置文件 aplication.yml 或者properties文件中配置了
二.依赖引入
<!--邮件服务--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
或者在创建项目的时候直接选择依赖
看它引入的依赖,可以看到 jakarta.mail
<dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> <version>1.6.4</version> <scope>compile</scope> </dependency>
三:配置信息
配置文件可以配置的属性值
列如配置如下:
#smtp服务主机 163邮箱则为smtp.163.com spring.mail.host=smtp.qq.com #服务协议 spring.mail.protocol=smtp # 编码集 spring.mail.default-encoding=utf-8 #发送邮件的账户 spring.mail.username=xxxxx@qq.com #授权码 spring.mail.password=xxxxx spring.mail.test-connection=true spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true
四:代码编写
JavaMailSenderImpl就是一个SpringBoot中用来发送邮件的一个实现类,我们需要将它注入到bean中,以供使用,也可以注入接口类JavaMailSender
//JavaMailSenderImpl 是JavaMailSender 实现类 两个选择一个都行 @Autowired JavaMailSender mailSender; @Autowired JavaMailSenderImpl javaMailSender;
由于每一封邮件都有固定的内容 例如 收件人信息 邮件内容 邮件标题 那么我们充分利用java面向对象的特性,我们吧邮件发送抽取为一个对象,这里省去了set\get以及全参数构造方法
public class EmailEntity implements Serializable { /** * 邮件接收方,可多人 */ private String[] tos; /** * 邮件主题 */ private String subject; /** * 邮件内容 */ private String content; }
肯定有人纳闷了,那么接收方有了,发送方呢?
发送一方,肯定就是我们自身拿到的授权码账号啊 ,我们获取账户客户端授权码其目的就是为了让代码代替我们自身邮箱 向其他邮箱发送信息而已。
获取发送方账户信息
@Value("${spring.mail.username}") private String from;
统一说明: JsonReturn 为我项目自定义的Ajax 响应而已,通常结合 RestController 或者Responsebody向前端返回JSON数据
public JsonReturn commonEmail(ToEmail toEmail) { //创建简单邮件消息 SimpleMailMessage message = new SimpleMailMessage(); //谁发的 message.setFrom(from); //谁要接收 message.setTo(toEmail.getTos()); //邮件标题 message.setSubject(toEmail.getSubject()); //邮件内容 message.setText(toEmail.getContent()); try { mailSender.send(message); return JsonReturn.buildSuccess(toEmail.getTos(), "发送普通邮件成功"); } catch (MailException e) { e.printStackTrace(); return JsonReturn.buildFailure("普通邮件方失败"); }
五:多样式内容发送
上面发送的内容死板不好看啊,想搞个有特色的的,搞个有样式的邮件或者有资源携带的邮件
html邮件发送
public JsonReturn htmlEmail(ToEmail toEmail) throws MessagingException { //创建一个MINE消息 MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper minehelper = new MimeMessageHelper(message, true); //谁发 minehelper.setFrom(from); //谁要接收 minehelper.setTo(toEmail.getTos()); //邮件主题 minehelper.setSubject(toEmail.getSubject()); //邮件内容 true 表示带有附件或html minehelper.setText(toEmail.getContent(), true); try { mailSender.send(message); return JsonReturn.buildSuccess(toEmail.getTos() + toEmail.getContent(), "HTML邮件成功"); } catch (MailException e) { e.printStackTrace(); return JsonReturn.buildFailure("HTML邮件失败"); } }
测试
@Test public void testHtml() throws Exception { String content = "<html>\n" + "<body>\n" + " <h1>这是Html格式邮件!,不信你看邮件,我字体比一般字体还要大</h1>\n" + "</body>\n" + "</html>"; toEmailService.htmlEmail(new ToEmail(new String[]{"248721866@qq.com"},"Html邮件",content)); }
含静态资源邮件发送
public JsonReturn staticEmail(ToEmail toEmail, MultipartFile multipartFile, String resId) { //创建一个MINE消息 MimeMessage message = mailSender.createMimeMessage(); try { MimeMessageHelper helper = new MimeMessageHelper(message, true); //谁发 helper.setFrom(from); //谁接收 helper.setTo(toEmail.getTos()); //邮件主题 helper.setSubject(toEmail.getSubject()); //邮件内容 true 表示带有附件或html //邮件内容拼接 String content = "<html><body><img width='250px' src=\'cid:" + resId + "\'>" + toEmail.getContent() + "</body></html>"; helper.setText(content, true); //蒋 multpartfile 转为file File multipartFileToFile = MultipartFileToFile(multipartFile); FileSystemResource res = new FileSystemResource(multipartFileToFile); //添加内联资源,一个id对应一个资源,最终通过id来找到该资源 helper.addInline(resId, res); mailSender.send(message); return JsonReturn.buildSuccess(toEmail.getTos() + toEmail.getContent(), "嵌入静态资源的邮件已经发送"); } catch (MessagingException e) { return JsonReturn.buildFailure("嵌入静态资源的邮件发送失败"); } }
因为我当前没有使用文件服务器嘛,并未使用文件上传的URL 而是直接向接口传的multipartFile文件对象,但是邮件需要的是File对象,所以我们这里需要将multipartFile 转为 File
private File MultipartFileToFile(MultipartFile multiFile) { // 获取文件名 String fileName = multiFile.getOriginalFilename(); // 获取文件后缀 String prefix = fileName.substring(fileName.lastIndexOf(".")); // 若需要防止生成的临时文件重复,可以在文件名后添加随机码 try { File file = File.createTempFile(fileName, prefix); multiFile.transferTo(file); return file; } catch (Exception e) { e.printStackTrace(); } return null; }
发附件需要注意的是一个静态资源要对应一个ID ,ID没有讲究 别重复了就行
带附件邮件发送
public JsonReturn enclosureEmail(ToEmail toEmail, MultipartFile multipartFile) { //创建一个MINE消息 MimeMessage message = mailSender.createMimeMessage(); try { MimeMessageHelper helper = new MimeMessageHelper(message, true); //谁发 helper.setFrom(from); //谁接收 helper.setTo(toEmail.getTos()); //邮件主题 helper.setSubject(toEmail.getSubject()); //邮件内容 true 表示带有附件或html helper.setText(toEmail.getContent(), true); File multipartFileToFile = MultipartFileToFile(multipartFile); FileSystemResource file = new FileSystemResource(multipartFileToFile); String filename = file.getFilename(); //添加附件 helper.addAttachment(filename, file); mailSender.send(message); return JsonReturn.buildSuccess(toEmail.getTos() + toEmail.getContent(), "附件邮件成功"); } catch (MessagingException e) { e.printStackTrace(); return JsonReturn.buildFailure("附件邮件发送失败" + e.getMessage()); } }
交流公众号:java一号