SpringCloud邮件工具类

简介

SpringCloud使用的邮件工具和Springboot中的一样,都可以使用spring-boot-starter-mail起步依赖来实现。本文将提供两个邮件工具方法,分别是发送带有单个附件的方法和发送带有多个附件的方法,二者只是入参不同而已。本文还将介绍实际使用中遇到的问题及解决方法。

一.添加Maven依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

二.在配置文件Properties.xml中添加邮件配置

配置文件需要修改前三行配置,你需要指定一个邮箱账号和密码,用其来发送邮件。这个账号可以是QQ邮箱,也可以是网易邮箱,都可以。

根据选择邮箱的不同,host属性值也可能不同,这个地方需要调试,如果第一次就像成功,在下面填入QQ邮箱账号密码即可,host我已经给出,等你跑通了程序,在来测试或替换成你们公司的官方邮箱。

spring.mail.host=smtp.exmail.qq.com
spring.mail.username=填写你的邮箱账号(格式:1000@qq.com)
spring.mail.password=填写你的邮箱密码
spring.mail.properties.mail.smtp.auth=true
spring.mail.default-encoding=UTF-8
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
# 连接时间限制(毫秒)
spring.mail.mail.smtp.connectiontimeout=10000
# 发送时间限制(毫秒)
spring.mail.mail.smtp.writetimeout=5000
# 本地不配置端口,默认端口25也可以发送,上线若连接失败,改下端口
#spring.mail.port=465
#spring.mail.properties.mail.smtp.socketFactory.port=465

三.邮箱工具类(EmailUtils.java)

这里面提供两个方法,只需改下包名即可使用。


package com.blog.commons.mail;
import java.util.ArrayList;
import java.util.List;

import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.ObjectUtils;

import com.blog.commons.bean;

import lombok.extern.slf4j.Slf4j;

/**
 * @project commons-util
 * @description: 电子邮件工具类
 * @author 大脑补丁
 * @create 2020-03-17 20:32
 */
@Slf4j
public class EmailUtils {

    /**
     * 发送带有单个附件的邮件
     * 
     * @param mailSender
     *            邮件工具实例 (客户端通过 @Autowired JavaMailSender javaMailSender 注入即可使用)
     * 
     * @param fromEmail
     *            发件人邮箱地址(格式:abc@xxx.com)
     * @param toEmail
     *            收件人邮箱地址(格式:abc@xxx.com)
     * @param subject
     *            主题
     * @param content
     *            正文
     * @param attachment
     *            附件(若为null则不添加附件)
     * @return 0:失败,1:成功
     * 
     * @author 大脑补丁 on 2020-03-17 22:25
     */
    public static Integer sendMailAttachment(JavaMailSender mailSender, String fromEmail, String toEmail,
        String subject, String content, Attachment attachment) {
        // 附件名完整显示
        System.setProperty("mail.mime.splitlongparameters", "false");
        MimeMessage message = mailSender.createMimeMessage();
        // 1:成功;0:失败
        Integer result = 1;
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            helper.setFrom(fromEmail);
            helper.setTo(toEmail);
            helper.setSubject(subject);
            helper.setText(content, true);
            if (!ObjectUtils.isEmpty(attachment) && !ObjectUtils.isEmpty(attachment.getFileName())
                && !ObjectUtils.isEmpty(attachment.getFilePath())) {
                try {
                    FileSystemResource file = new FileSystemResource(attachment.getFilePath());
                    // helper.addAttachment(attachment.getFileName(), file);
                    // 附件中文名编码,B:Base64编码格式
                    helper.addAttachment(MimeUtility.encodeWord(attachment.getFileName(), "UTF-8", "B"), file);
                } catch (Exception e) {
                    // 如果存在附件,但添加附件时出错,则标记邮件发送结果为失败
                    result = 0;
                    e.printStackTrace();
                }
            }
            if (result == 1) {
                // 若存在附件且附件添加成功时才发送;若不存在附件,则直接发送
                mailSender.send(message);
            }
            log.info("邮件发送成功,收件人地址:" + toEmail);
            return result;
        } catch (Exception e) {
            log.error("邮件发送出现异常,收件人地址:" + toEmail, e);
        }
        return result;
    }

    /**
     * 发送带有多个附件的邮件
     * 
     * @param mailSender
     *            邮件工具实例 (客户端通过 @Autowired JavaMailSender javaMailSender 注入即可使用)
     * 
     * @param fromEmail
     *            发件人邮箱地址(格式:abc@xxx.com)
     * @param toEmail
     *            收件人邮箱地址(格式:abc@xxx.com)
     * @param subject
     *            主题
     * @param content
     *            正文
     * @param List<Attachment>
     *            多个附件列表
     * @return 0:失败,1:成功
     * @author 大脑补丁 on 2020-03-17 22:16
     */
    public static Integer sendMailAttachments(JavaMailSender mailSender, String fromEmail, String toEmail,
        String subject, String content, List<Attachment> attachments) {
        System.setProperty("mail.mime.splitlongparameters", "false");
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            helper.setFrom(fromEmail);
            helper.setTo(toEmail);
            helper.setSubject(subject);
            helper.setText(content, true);
            if (!ObjectUtils.isEmpty(attachments)) {
                attachments.forEach((attachment) -> {
                    try {
                        // 加载文件资源,作为附件
                        FileSystemResource file = new FileSystemResource(attachment.getFilePath());
                        // 添加附件
                        helper.addAttachment(MimeUtility.encodeWord(attachment.getFileName(), "UTF-8", "B"), file);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
            mailSender.send(message);
            log.info("邮件发送成功,收件人地址:" + toEmail);
            return 1;
        } catch (Exception e) {
            log.error("邮件发送出现异常,收件人地址:" + toEmail, e);
        }
        return 0;
    }
}

四.邮件对象类(Attachment.java)

  • 上面工具类使用了一个附件对象,对象有两个属性,一个是附件名称、一个是文件路径。
  • 附件名称是在邮件附件中的文件名,而不是本地文件名。文件路径要注意,文件路径要传递完整路径,如:C:\temp\文档.txt,因为要同过文件流读取这个文件,路径不能只写到文件夹。
  • 下面的实体类用到了lombok.jar,如果你没有使用该插件,将下方类名上的3个注解删除,并自行增加Getter\Setter方法即可。
package com.blog.commons.bean;

import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @project commons-util
 * @description: 邮件附件
 * @author 大脑补丁
 * @create 2020-03-17 22:37
 */
@Data
@Accessors(chain = true)
@RequiredArgsConstructor(staticName = "of")
public class Attachment {
    /** 文件名称 */
    private String fileName;
    /** 文件路径 */
    private String filePath;
}

五.如何使用

  1. 在需要发送邮件的类中,通过@Autowired,注入邮件对象JavaMailSender
  2. 在需要发送邮件的类中,通过@Value("${spring.mail.username}"),注入配置文件中,你的邮箱地址。(为什么不写死邮箱?因为SpringCloud微服务每个服务模块的邮箱账号都不同,比如订单有订单的邮箱,广告有广告的邮箱。不可能只用一个邮箱账号发送所有功能的邮件,否则很容易被邮箱客户端自动列入黑名单,用户收到的文件直接进入了垃圾箱)
@Value("${spring.mail.username}")
private String email;
  1. 创建附件对象。
Attachment attachment = new Attachment();
//邮件中的附件名,可以与路径中的不一样
attachment.setFileName("你的附件名.txt");
//硬盘中的文件名,必须写扩展名。
attachment.setFilePath("C:temo\文档.txt");
  1. 发送邮件
    发送成功返回1,失败返回0。
Integer result = EmailUtils.sendMailAttachment(javaMailSender, email, "客户1@qq.com","标题", "正文。",attachment );

两个工具方法的使用示例

    private void demo() {

        // 步骤一:注入邮件工具实例。
        // @Autowired
        // private JavaMailSender javaMailSender;

        // 步骤二:注入公司邮箱,配置文件中,微服务模块对应的邮箱地址,每个服务邮箱地址可能不相同。
        // @Value("${spring.mail.username}")
        // private String email;

        // 步骤三:发送邮件。

        // 邮件工具1:发送单个附件邮件
        // Integer oneAttachment = EmailUtils.sendMailAttachment(javaMailSender, "业务模块1专用邮箱@163.cn", "客户1@qq.com",
        // "我是标题", "您好!我是正文。", Attachment.of().setFileName("邮件附件名称.xls").setFilePath("C:\\Workspace\\本地文件名称.xlsx"));

        // 邮件工具2:发送多个附件邮件
        // 创建多个附件
        List<Attachment> attachments = new ArrayList<Attachment>();
        attachments.add(Attachment.of().setFileName("邮件附件名称1.xlsx").setFilePath("C:\\Workspace\\本地文件名称1.xlsx"));
        attachments.add(Attachment.of().setFileName("邮件附件名称2.xlsx").setFilePath("C:\\Workspace\\本地文件名称2.xlsx"));
        // 发送多个附件邮件
        // Integer multiAttachment = EmailUtils.sendMailAttachments(javaMailSender, "业务模块专用邮箱@cnecloud.cn",
        // "客户@qq.com","我是标题", "您好!我是正文。", attachments);
    }

六.Java正则表达式校验邮件合法性

可以在控制层,验证用户输入的邮箱是否合法的方法:

Pattern pattern = Pattern.compile(".+@.+\\.[a-z]+");
Matcher matcher = pattern.matcher(sendBillInput.getEmail());
    if (!matcher.matches()) {
        log.error("邮箱格式不合法");
    }

七.邮件发送中遇到的问题

1.附件中文名乱码
解决方法:

在工具类中添加编码即可。

MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
// 附件中文名编码,参数"B"含义:Base64编码格式
helper.addAttachment(MimeUtility.encodeWord(attachment.getFileName(), "UTF-8", "B"), file);
2.邮件附件名称,显示不全或被转换成了其他字符。

如:附件名称定义为:2021年苹果公司销售额记录单.xls,但QQ邮箱异常显示为:2021年苹果公____司销售额E7__.xls,网易邮箱异常显示为:ATT0002.bin,这是怎么回事呢?

解决方法:

这个问题不同于乱码,这不是附件名称乱码,而是附件名称没有正常的显示全,我们再邮件工具中增加下行配置解决:

 System.setProperty("mail.mime.splitlongparameters", "false");

八.总结

关于SpringCloud、或Springboot中发送邮件的方法和常见问题,都分享在这了。掌握了这些,在SpringCloud中使用邮件已经足够了。当然你可以将此工具类作为一个单独的SpringCloud邮件微服务进行使用了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值