javamail: UrlDataSource获取网络文件作为邮件的附件|javamail发送二进制流附件的问题

Posted achengmu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javamail: UrlDataSource获取网络文件作为邮件的附件|javamail发送二进制流附件的问题相关的知识,希望对你有一定的参考价值。

https://www.cnblogs.com/younldeace/p/5193103.html

最近做个邮件发送功能,要内嵌图片并有附件。

需求很奇怪,图片和附件文件是放在ftp服务器上的,查了下javamail的文档。

添加附件方法如下

MimeBodyPart messageBodyPart=new MimeBodyPart();
DataSource dataSource1=new FileDataSource("d:/xx.doc");
//DataSource dataSource1=new UrlDataSource("url");

  

按照这个api,只能先把ftp文件下载到本地,然后再读,多次一句,还额外增加了读写的成本。为什么这个api不直接提供个二进制流的DataSource呢。

百度了很久也没找到。后来google了一下,马上找到解决方案。

就是ByteArrayDataSource,这是javamail util包里的一个api。

附上完整的内嵌图片, 另发附件的javamail代码。

package com.allianture.core.sendEmail.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Security;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.URLDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
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 javax.mail.util.ByteArrayDataSource;

import com.allianture.platform.common.api.config.FtpConfig;
import com.allianture.platform.common.api.util.FtpUtils;
import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;

public class TestMail {
    // static int port = 587;

    static String server = "smtp.exmail.qq.com";// 邮件服务器mail.cpip.net.cn

    static String from = "AA";// 发送者,显示的发件人名字

    static String user = "[email protected]";// 发送者邮箱地址

    static String password = "aaaa";// 密码

    public static void sendEmail() throws UnsupportedEncodingException {
        try {
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            Properties props = new Properties();
            props.setProperty("mail.smtp.socketFactory.class",
                    "javax.net.ssl.SSLSocketFactory");
            props.setProperty("mail.smtp.socketFactory.fallback", "false");
            props.setProperty("mail.store.protocol", "smtp");
            props.setProperty("mail.smtp.host", "smtp.exmail.qq.com");
            props.setProperty("mail.smtp.port", "465");
            props.setProperty("mail.smtp.socketFactory.port", "465");
            props.put("mail.smtp.auth", "true");
            Session session = Session.getInstance(props, new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(user, password);
                }
            });
            MimeMessage msg = new MimeMessage(session);
            String nick=javax.mail.internet.MimeUtility.encodeText("aaa"); 
            msg.setFrom(new InternetAddress(user, nick));
            msg.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse("[email protected]", false));
            msg.setSubject("testest");
            msg.setSentDate(new Date());
            
            MimeMultipart multipart = new MimeMultipart("mixed");
            // 邮件内容,采用HTML格式
            MimeBodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.removeHeader("Content-Type");
            messageBodyPart.removeHeader("Content-Transfer-Encoding");
            messageBodyPart.addHeader("Content-Type", "text/html; charset=gbk");
            messageBodyPart.addHeader("Content-Transfer-Encoding", "base64");
            messageBodyPart.setContent(getHtml(), "text/html;charset=GBK");
            
            
            multipart.addBodyPart(messageBodyPart);
            //内嵌图片
            messageBodyPart=new MimeBodyPart();
            //DataSource dataSource=new FileDataSource("d:/1.png");
            URL url;
            try {
                url = new URL("https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png");
                DataSource dataSource=new URLDataSource(url);
                DataHandler dataHandler=new DataHandler(dataSource);
                messageBodyPart.setDataHandler(dataHandler);
                messageBodyPart.setContentID("testi");

                multipart.addBodyPart(messageBodyPart);
                
                //添加附件
//                messageBodyPart=new MimeBodyPart();
//                DataSource dataSource1=new FileDataSource("d:/aa.doc");
//                dataHandler=new DataHandler(dataSource1);
//                messageBodyPart.setDataHandler(dataHandler);
//                messageBodyPart.setFileName(MimeUtility.encodeText(dataSource1.getName()));
                
                messageBodyPart=new MimeBodyPart();
                InputStream is=downloadFtp();
                //DataSource dataSource1=new FileDataSource("d:/aa.doc");
                DataSource dataSource1=new ByteArrayDataSource(is, "application/png");
                dataHandler=new DataHandler(dataSource1);
                messageBodyPart.setDataHandler(dataHandler);
                messageBodyPart.setFileName(MimeUtility.encodeText("aa.doc"));
                
                multipart.addBodyPart(messageBodyPart);
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
          
            
            msg.setContent(multipart);
            msg.saveChanges();
            
            Transport.send(msg);

        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    public static String getHtml(){
        InputStream is;
        try {
            is = new FileInputStream("d:/测试.html");
            byte[] b = new byte[1024];
            int size = is.read(b);
            return new String(b,0,size);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
        
    }
    public static void main(String args[]) throws UnsupportedEncodingException {

        sendEmail();// 收件人
        //System.out.println(getHtml());
        //downloadFtp();
        System.out.println("ok");
    }
    
    public static InputStream downloadFtp(){
        try {
            FtpUtils ftpUtils = new FtpUtils();
            FtpConfig config = new FtpConfig();
            config.setEncode("GBK");// 设置编码
            config.setServer("101.31.116.513");// 设置服务
            config.setPort(21);// 设置端口
            config.setUsername("weblogic");// 设置用户名
            config.setPassword("weblogic");// 设置密码
            config.setLocation("/home/weblogic/ebiz/mailtest");
            boolean flag = ftpUtils.connectServer(config);
            System.out.println(flag);
            System.out.println(ftpUtils.getFileList());
            InputStream  is=ftpUtils.getFtpClient().retrieveFileStream("aa.doc");
            ftpUtils.closeServer();
            return is;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
        
    }
}

  

测试.html

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <title>e</title>
    <style>
    </style>
</head>

<body>
   <h1>dusen</h1>
   <span style="color:red">this is a test email</span>
   <div><img src="cid:testi"></div>
   <div><img src="cid:testi2"></div>
</body>
</html>

  

还有一点,qq的企业邮箱要加ssl

 

以上是关于javamail: UrlDataSource获取网络文件作为邮件的附件|javamail发送二进制流附件的问题的主要内容,如果未能解决你的问题,请参考以下文章

URLdatasource的dataimporthandler中的SOLR子文档定义

JavaMail获取已发送邮件

在 JavaMail 中获取 html 电子邮件内容

Javamail:无法从我的大学电子邮件服务中获取附件

SSL上的JavaMail IMAP非常慢 - 批量获取多条消息

如何使用 JavaMail 获取邮件帐户中可用文件夹的列表