邮件发送功能-带附件

在这里插入图片描述
JAVA邮件发送的大致过程是这样的的:
1、构建一个properties文件,该文件中存放SMTP服务器地址等参数。
2、通过构建的properties文件和javax.mail.Authenticator具体类来创建一个javax.mail.Session。Session的创建,就相当于登录邮箱一样。剩下的自然就是新建邮件。
3、构建邮件内容,一般是javax.mail.internet.MimeMessage对象,并指定发送人,收信人,主题,内容等等。
4、使用javax.mail.Transport工具类发送邮件。

以163邮箱为例,获取邮箱授权码步骤:

  1. 点击上方设置按钮,再点击POP3/SMTP/IMAP。
  2. 开启对应服务授权码,需要发送短信开启,只显示一次
  3. 下面有对应的服务器地址、授权码管理,如果不用可以删除。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SMTP服务器地址:一般是 smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com。

SMTP协议:通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。

POP3协议:通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。

代码实现:

 //文件暂存地址
@Value("D:/file/tmp")
private String fileTmp;

//发送人邮箱
@Value("xxxxxxxx@163.com")
private String senderEmail;

//发送人邮箱授权码
@Value("ACJGFOSNF9866GFF")
private String senderCode;

//服务器地址
@Value("smtp.163.com")
private String emailSMTPHost;

//端口 只有使用内部邮箱时才会使用端口
//@Value("465")
//private Integer emailSMTPPort;

//收件人邮箱
@Value("xxxxxxx@163.com")
private String receiveMailAccount;

//抄送人邮箱
@Value("xxxxxxx@163.com")
private String ccMailAccount;
@Value("xxxxxxx@qq.com")
private String ccMailAccount1;
@Value("xxxxxxx@qq.com")
private String ccMailAccount2;

/**
 * 发送邮件内容
 *
 * @param file 邮件内容
 */
@PostMapping("sendMessage")
public Result sendMessage(@RequestParam("file") MultipartFile file) {
    log.info("开始发送邮件! 文件名称:{}",file.getOriginalFilename());
    //抄送人
    Vector<String> toList = new Vector<>() ;
    toList.addElement(ccMailAccount);
    toList.addElement(ccMailAccount1);
    toList.addElement(ccMailAccount2);
    String res = EmailUtils.sendMail(file, fileTmp, senderEmail, senderCode, emailSMTPHost,
            receiveMailAccount, toList,emailSMTPPort);
    if (!res.equals("success")){
        return Result.create("邮件发送失败!",ResultCode.NFC_FAILURE);
    }
    return Result.create("邮件发送成功!",ResultCode.SUCCESS);
}

MIME(多用途互联网邮件扩展类型)

MimeBodyPart类

javax.mail.internet.MimeBodyPart类
表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来。

MimeMultipart类

javax.mail.internet.MimeMultipart是抽象类
Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象

package .xxxx.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Vector;

@Slf4j
public class EmailUtils {


    /**
     * 发送邮件
     * @param file 邮件内容
     *
     */
    public static String sendMail(MultipartFile file, String fileTmp, String senderEmail, String senderCode,
                                  String emailSMTPHost, String receiveMailAccount, Vector<String> toList,
                                  Integer emailSMTPPort) {
        try {
            Properties props = new Properties();
            props.setProperty("mail.transport.protocol", "smtp");// 使用的协议
            props.setProperty("mail.smtp.host", emailSMTPHost);// 发件人的邮箱的SMTP服务器地址
            //props.setProperty("mail.smtp.port", String.valueOf(emailSMTPPort));//只有内部邮箱才会使用端口,默认为25,加密为465 不建议使用默认
            props.setProperty("mail.smtp.auth", "true");// 需要请求认证
            //props.setProperty("mail.smtp.ssl.enable", "true");//开启ssl加密,不使用内部邮箱不用端口时,可以不打开ssl

            Session session = Session.getInstance(props);//得到会话对象实例

            session.setDebug(false);//是否打印详细日志

            MimeMessage message = createMimeMessage(session, file,senderEmail,receiveMailAccount,
                    fileTmp, toList);//获取邮件对象(封装了一个方法)

            Transport transport = session.getTransport();

            transport.connect(senderEmail, senderCode);//连接发送人的邮箱账户

            // 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
            transport.sendMessage(message, message.getAllRecipients());

            // 7. 关闭连接
            transport.close();

            //删除临时存放文件
            FileUtils.deleteFolder(fileTmp);
            log.info("邮件发送成功");
            return "success";
        } catch (Exception e) {
            log.error("发送邮件失败");
        }
        return "";
    }


    /**
     * 创建发送邮件内容
     * @param session session
     * @param mainFile    邮件附件
     */
    private static MimeMessage createMimeMessage(Session session, MultipartFile mainFile,
                                                 String senderEmail, String receiveMailAccount,
                                                 String fileTmp,Vector<String> toList) {
        MimeMessage message = null;
        try {
            // 1. 创建一封邮件
            message = new MimeMessage(session);

            // 2. From: 发件人
            message.setFrom(new InternetAddress(senderEmail, "发件人", "UTF-8"));

            // 3. 设置收件人、抄送人、密送人
            //MimeMessage.RecipientType.TO:收件类型;MimeMessage.RecipientType.CC:抄送类型;MimeMessage.RecipientType.BCC:密送类型
            message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMailAccount, "收件人", "UTF-8"));
            InternetAddress[] addArr = null;
            // 设置抄送人地址
            if ((toList != null) && (toList.size() != 0)) {
                addArr = new InternetAddress[toList.size()];
                for (int i = 0; i < toList.size(); i++) {
                    String ccMailStr =  toList.get(i);
                    addArr[i] = new InternetAddress(ccMailStr);
                }
                message.setRecipients(Message.RecipientType.CC, addArr); // 设置抄送人地址
            }
//            message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(ccMailAccount, "抄送人", "UTF-8"));
//            message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(bccmailAccount, "密送人", "UTF-8"));

            // 4. Subject: 邮件主题
            message.setSubject("这是邮件主题!", "UTF-8");

            // 5. Content: 邮件正文(可以使用html标签)
            //一个Multipart对象包含一个或多个bodypart对象,组成邮件正文
            MimeMultipart multipart = new MimeMultipart();
            MimeBodyPart contentPart = new MimeBodyPart();
            contentPart.setText("这是邮件正文","UTF-8");
            contentPart.setHeader("Content-Type", "text/html; charset=UTF-8");
            multipart.addBodyPart(contentPart);
            MimeBodyPart filePart = new MimeBodyPart();
            File file = MultipartFileToFile(mainFile,fileTmp);
            if (!ObjectUtils.isEmpty(file)){
                DataHandler handler = new DataHandler(new FileDataSource(file));
                filePart.setDataHandler(handler);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String formatDate = sdf.format(new Date());
                String name = file.getName();
                String suffix = name.substring(name.lastIndexOf("."));
                //对文件名进行编码,防止出现乱码
                String fileName = "这是附件名称"+formatDate+suffix;
                filePart.setFileName(fileName);
                multipart.addBodyPart(filePart);
                message.setContent(multipart);

                // 6. 设置发件时间
                message.setSentDate(new Date());

                // 7. 保存设置
                message.saveChanges();
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("创建发送邮件内容失败!", e);
        }
        return message;

    }

    /**
     * 将MultipartFile转换为File
     * @param multiFile multiFile
     * @return file
     */
    public static File MultipartFileToFile(MultipartFile multiFile,String fileTmp) {
        File directory = new File(fileTmp);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        if(!StringUtils.isEmpty(fileName)){
            String prefix = fileName.substring(fileName.lastIndexOf("."));
            // 若须要防止生成的临时文件重复,能够在文件名后添加随机码
            try {
                File file = File.createTempFile(String.valueOf(System.currentTimeMillis()), prefix, new File(fileTmp));
                multiFile.transferTo(file);
                return file;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
   	  }
   	}

pom文件依赖:

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version>
</dependency>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简单的控制台程序 主要是为了学习之用 本人花时间编写。为了和大家分享和学习用,如有什么错误或认为本人哪里处理不当 请和我联系~~ 内容: main.cpp 就一个cpp文件 //1.首先需要连接邮件服务器 这里用socket 邮件服务器端口 25 //2.现在就是和服务器对话了 //3.结束 #include #include #include #include #include #include #include #include #include #include #include #include #pragma comment(lib,"WS2_32.lib") using namespace std; /*加附件的版本*/ //base64编码 string Base64Encode(LPCTSTR lpszSrc); //base64解码 string Base64Decode(LPCTSTR lpszSrc); //读文件数据 bool ReadFromFile(const char* pszFilename,string &filename); unsigned char* m_pbText; int main() { //1.首先需要连接邮件服务器 这里用socket 邮件服务器端口 25 WSADATA Wsa; //进行WINSOCK的设置 WSAStartup(0x0101,&Wsa); SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); SOCKADDR_IN sin; LPHOSTENT lphost = gethostbyname("smtp.163.com");//这里是用网易的邮件服务器 也可以修改 if(lphost) sin.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr; else { printf("%s\n","获取地址失败"); return 1; } sin.sin_family = AF_INET; //注意邮件服务器的侦听端口 25 sin.sin_port = htons(IPPORT_SMTP); //连接服务器 if(connect(s,(LPSOCKADDR)&sin,sizeof(sin))==SOCKET_ERROR) { printf("%s\n","连接错误"); return 1; } printf("%s\n","连接成功"); //接收服务器初次回应 char buff[1024]; memset(buff,0,sizeof(buff)); recv(s,buff,sizeof(buff),0); printf("服务说:%s\n",buff); /////上面已经完成连接了///// string szLine="\r\n";//相当于你按下回车 //2.现在就是和服务器对话了 //问候服务器 string szHelo = "HELO smtp.163.com" + szLine; printf("我说:%s\n",szHelo.c_str()); send(s,szHelo.c_str(),szHelo.length(),0); memset(buff,0,sizeof(buff)); recv(s,buff,sizeof(buff),0); printf("服务说:%s\n",buff); //请求验证用户密码(需要编码) string szAL = "auth login" + szLine; //发送验证命令 printf("我说:%s\n",szAL.c_str()); send(s,szAL.c_str(),szAL.length(),0); memset(buff,0,sizeof(buff)); recv(s,buff,sizeof(buff),0); // printf("服务说:%s\n",buff); //服务器会回答说 可以输入帐号 //发送帐号 string szUser; .... 具体自己下载运行即可 装个VC6.0 即可

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值