通过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可以通过后缀名来判断
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方法获取输入流。如果是其他类型的流,写在这个方法中打开即可。
com.sun.mail
javax.mail
1.6.1
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("[email protected]", "测试主题", "测试主题", 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;
}
}