【Java】javax.mail发送邮件

戴凯歌
2023-12-01

maven依赖

        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>

 

1、controller

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.internet.MimeMessage;
import javax.validation.Valid;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/v*/personal/mail")
public class MailController extends BaseController {

    @Autowired
    private MailService mailService;

    @Value("${pm.mail.attachment.temp}")
    private String prefix;

    /**
     * 发送邮件
     */
    @PostMapping("/send")
    public Result send(@Valid MailProtocol.Send.Input input, List<MultipartFile> file, BindingResult bindingResult) {

        validateArgs(bindingResult);

        List<String> filesPath = getFilesPath(file);

        mailService.sendMail(StringUtil.join(input.getTo(), ","), StringUtil.join(input.getCc(), ","),
                StringUtil.join(input.getBcc(), ","), input.getSubject(), input.getContent(), filesPath);

        return succeed();
    }

    /**
     * 暂存文件
     *
     * @param attachments 附件
     * @return 附件路径
     */
    private List<String> getFilesPath(List<MultipartFile> attachments) {

        if (isEmpty(attachments)) {
            return new ArrayList<>();
        }

        List<String> filesPath = new ArrayList<>(attachments.size());

        String path = prefix + uuid() + "/";

        File root = new File(path);

        if (!root.exists()) {
            root.mkdirs();
        }

        try {
            for (MultipartFile file : attachments) {

                String filePath = path + file.getOriginalFilename();

                filesPath.add(filePath);

                IOUtils.copy(file.getInputStream(), new FileOutputStream(filePath));
            }
        } catch (IOException e) {
            if (logger.isInfoEnabled()) {
                logger.info("[save temp file error]========{}", e.getMessage());
            }
        }

        return filesPath;
    }
}

 

2、service

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Properties;

/**
 * @ Author:yl1794
 * @ Date:2019/10/29 9:03
 * @ Description:邮件服务
 */
@Service
public class MailService extends BaseService {

    @Value("${pm.mail.sender.username}")
    private String username;

    @Value("${pm.mail.sender.password}")
    private String password;

    @Value("${pm.mail.smtp.host}")
    private String host;

    @Value("${pm.mail.smtp.port}")
    private int port;

    @Async
    public void sendMail(String to, String cc, String bcc, String subject, String content, List<String> attachments) {

        if(logger.isInfoEnabled()){
            logger.info("[SEND_MAIL]========to: {}, cc: {}, bcc: {}, attachments: {}", to, cc, bcc, attachments);
        }

        Properties props = new Properties();

        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.ssl.checkserveridentity", "false");
        props.put("mail.smtp.ssl.trust", host);
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);

        Session session = Session.getInstance(props,
                new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });

        try {

            Message message = getMimeMessage(session, to, cc, bcc, subject, content, attachments);

            // 发送邮件
            Transport.send(message);

        } catch (MessagingException | IOException e) {
            throwInternalServerException(e.getMessage());
        } finally {
            if (isNotEmpty(attachments)) {
                delTmpFiles(attachments.get(0));
            }
        }
    }

    /**
     * 创建邮件的实例对象
     *
     * @param session     session对象
     * @param to          发送人
     * @param cc          抄送人
     * @param bcc         密送人
     * @param subject     主题
     * @param content     内容
     * @param attachments 附件
     * @return MimeMessage
     * @throws javax.mail.MessagingException
     * @throws IOException
     */
    private MimeMessage getMimeMessage(Session session, String to, String cc, String bcc, String subject, String content,
                                       List<String> attachments)
            throws javax.mail.MessagingException, IOException {

        MimeMessage message = new MimeMessage(session);

        message.setFrom(new InternetAddress(username));
        // 发件人别名设置
//        message.setFrom(new InternetAddress(MimeUtility.encodeText("我的昵称") + " <" + username + ">"));
//        message.setFrom(new InternetAddress(username,"我的昵称", "UTF-8"));

        // TO:发送、CC:抄送、BCC :密送
        if (isNotEmpty(to)) {
            message.setRecipients(Message.RecipientType.TO, new InternetAddress().parse(to));
        }

        if (isNotEmpty(cc)) {
            message.setRecipients(Message.RecipientType.CC, new InternetAddress().parse(cc));
        }

        if (isNotEmpty(bcc)) {
            message.setRecipients(Message.RecipientType.BCC, new InternetAddress().parse(bcc));
        }

        message.setSubject(subject, "UTF-8");

        //添加邮件的各个部分内容,包括文本内容和附件
        MimeMultipart multipart = new MimeMultipart();

        //设置邮件正文
        MimeBodyPart contentPart = new MimeBodyPart();
        contentPart.setContent(content, "text/html;charset=utf-8");
        multipart.addBodyPart(contentPart);

        // 添加附件
        addAttachments(multipart, attachments);

        message.setContent(multipart);
        message.saveChanges();

        return message;
    }

    /**
     * 添加附件(多个)
     *
     * @param multipart multipart
     * @param files     文件路径
     * @throws MessagingException
     * @throws UnsupportedEncodingException
     */
    private void addAttachments(MimeMultipart multipart, List<String> files) throws MessagingException, IOException {

        if (isEmpty(files)) {
            return;
        }

        for (String file : files) {
            MimeBodyPart messageBodyPart = new MimeBodyPart();
            DataHandler dataHandler = new DataHandler(new FileDataSource(file));
            messageBodyPart.setDataHandler(dataHandler);
            messageBodyPart.setFileName(MimeUtility.encodeText(dataHandler.getName()));
            multipart.addBodyPart(messageBodyPart);
        }
    }

//    private void addAttachments(MimeMultipart multipart, List<MultipartFile> files) throws MessagingException, IOException {
//
//        if (isEmpty(files)) {
//            return;
//        }
//
//        for (MultipartFile file : files) {
//            MimeBodyPart messageBodyPart = new MimeBodyPart();
//            ByteArrayDataSource dataSource = new ByteArrayDataSource(file.getInputStream(), file.getContentType());
//            DataHandler dataHandler = new DataHandler(dataSource);
//            messageBodyPart.setDataHandler(dataHandler);
//            messageBodyPart.setFileName(MimeUtility.encodeText(dataHandler.getName()));
//            multipart.addBodyPart(messageBodyPart);
//        }
//    }

    /**
     * 删除某个文件的父目录下所有文件(包括文件夹)
     *
     * @param filePath filePath
     * @throws IOException
     */
    private void delTmpFiles(String filePath) {

        if (isEmpty(filePath)) {
            return;
        }

        File file = new File(filePath);

        try {
            FileUtils.deleteDirectory(file.getParentFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        MailService mailService = new MailService();
//        mailService.sendMail("cqh@xxx.com,cqh@xxx.com", null, null, "主题test", "内容test444!", null);

    }

}

附:

邮件的抄送,密送的区别

1、抄送就是将邮件同时发送给收信人以外的人,用户所写的邮件抄送一份给别人,对方可以看见该用户的E-mail。

2、密送,只有发信的人知道密送给了谁,邮件接收者和抄送者都不知道发送者密送给了谁,但是接收密送的人知道是谁给他发的这封邮件,以及这份邮件本来发给了谁,并抄送给了谁,但不知道这封邮件同时又密送给了谁。

3、如A 发送邮件给B1、B2、B3,抄送给C1、C2、C3,密送给D1、D2、D3。

那么:

A知道自己发送邮件给了B1、B2、B3,并且抄送给了C1、C2、C3,密送给了D1、D2、D3。

B1知道这封是A发送给B1、B2、B3的邮件,并且抄送给了C1、C2、C3,但不知道密送给了D1、D2、D3。

C1知道这封是A发送给B1、B2、B3的邮件,并且抄送给了C1、C2、C3,但不知道密送给了D1、D2、D3。

D1知道这封是A发送给B1、B2、B3的邮件,并且抄送给了C1、C2、C3,而且密送给了自己,但不知道密送给了D2、D3。

 类似资料: