java mail使用IO流发送附件

需求

通过ftp获取文件输入流,将该输入流直接作为邮件附件发送。

实现方式

网上找了半天都没有合适的答案,之前有写过上传附件的方法,查看后发现,上传本地附件需要依赖FileDataSource,这个类继承了DataSource接口,所以突发奇想,能不能自己写一个类,继承这个接口,这样的话就可以实现

接口定义

package javax.activation;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public interface DataSource {
    InputStream getInputStream() throws IOException;

    OutputStream getOutputStream() throws IOException;

    String getContentType();

    String getName();
}

从这个接口可以知道,实现需要提供输入流,输出流,contentType,名称,因为这里是需要发送邮件,所以不需要提供输出流
然后就剩余name跟contentType了,name可以通过文件路径获取,也可以手动传入,contentType可以通过后缀名来判断

实现DataSource后的类

package com.itsm.email.mail;

import com.itsm.email.utils.SFTPUtil;

import javax.activation.DataSource;
import javax.activation.FileTypeMap;
import java.io.*;

public class SFTPDataSource implements DataSource {
    private String path;
    private SFTPUtil sftpUtil;

    public SFTPDataSource() {}

    public SFTPDataSource(String path, SFTPUtil sftpUtil) {
        this.path = path;
        this.sftpUtil = sftpUtil;
    }

    public InputStream getInputStream() throws IOException {
        return sftpUtil.get(path);
    }

    public OutputStream getOutputStream() throws IOException {
        return null;
    }

    public String getContentType() {
        return FileTypeMap.getDefaultFileTypeMap().getContentType(this.path);
    }

    public String getName() {
        return new File(path).getName();
    }
}

这里需要注意的事,inputStream不能提前传入,必须是调用getInputStream时开启,否则获取到的inputStream是关闭的,所以将SFTPUtile类传入,调用写好的get方法获取输入流。如果是其他类型的流,写在这个方法中打开即可。

引入jar包

<dependency>
	<groupId>com.sun.mail</groupId>
	<artifactId>javax.mail</artifactId>
    <version>1.6.1</version>
</dependency>

mail类实现

package com.itsm.ja_oa.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import java.util.Date;
import java.util.Properties;

public class Mail {
    private static Log log = LogFactory.getLog(Mail.class);
    /**主机名*/
    private String smtpHost;
    /**邮件地址*/
    private String address;
    /**邮件密码*/
    private String password;

    public static void main(String[] args) {
        String smtpHost = "";
        String address = "";
        String password = "";
        Mail mail = new Mail();
        mail.setSmtpHost(smtpHost);
        mail.setAddress(address);
        mail.setPassword(password);
        // sftp工具类,具体的流从哪来根据自己业务来弄
        SFTPUtil sftp = new SFTPUtil("username", "password", "host", 22);
        sftp.login();
        DataSource dataSource = new SFTPDataSource("/opt/test.txt", sftp);;
        mail.send("13734153210@163.com", "测试主题", "测试主题", dataSource);
        sftp.logout();

    }

    public Mail() {}

    public Mail(String smtpHost, String address, String password) {
        this.smtpHost = smtpHost;
        this.address = address;
        this.password = password;
    }

    public void send(String recipientAddress, String mailTile, String mailBody, DataSource dataSource)  {
        try {
            System.setProperty("mail.mime.splitlongparameters","false");
            Properties props = new Properties();
            //设置用户的认证方式
            props.put("mail.smtp.auth", "true");
            //设置传输协议
            props.put("mail.transport.protocol", "smtp");
            //设置发件人的SMTP服务器地址
            props.put("mail.smtp.host", smtpHost);
            props.put("mail.smtp.timeout", "300000");//设置链接超时
            props.put("mail.smtp.port", 465);
            props.put("mail.smtp.ssl.socketFactory","javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.ssl.socketFactory.class","javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.ssl.socketFactory.port",465);
            props.put("mail.smtp.socketFactory.fallback", "false");
            props.put("mail.smtp.ssl.enable", "true");
            Session session = Session.getInstance(props);

            //创建一封邮件的实例对象
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress(address));
            msg.setRecipients(MimeMessage.RecipientType.TO, recipientAddress);
            msg.setSubject(mailTile, "utf-8");
            msg.setSentDate(new Date());

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

            MimeBodyPart attachment = new MimeBodyPart();
            // 读取文件
            DataHandler dh = new DataHandler(dataSource);
            // 将附件数据添加到"节点"
            attachment.setDataHandler(dh);
            // 设置附件的文件名(需要编码)
            String filename = MimeUtility.encodeText(dh.getName()).trim();
            attachment.setFileName(filename);
            mm.addBodyPart(attachment);
            // 混合关系
            mm.setSubType("mixed");
            msg.setContent(mm);

            //4、根据session对象获取邮件传输对象Transport
            Transport transport = session.getTransport();
            //设置发件人的账户名和密码
            transport.connect(address, password);
            //发送邮件,并发送到所有收件人地址,message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
            transport.sendMessage(msg,msg.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getSmtpHost() {
        return smtpHost;
    }

    public void setSmtpHost(String smtpHost) {
        this.smtpHost = smtpHost;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值