用Java Mail发送带有图片附件的html格式邮件

转载 2007年09月19日 13:46:00
用Java Mail发送带有图片的html格式的邮件,针对于显示图片,一般有两种方法。

1. 图片存在于服务器上,我们只需要把图片在服务器的的链接放进去即可。
这种发式比较简单,但是这种方法有些缺陷:
图片不支持离线浏览;
每次浏览邮件需要访问web服务,增加服务器负担;
若图片以二进制的方式存在于数据库或是动态生成的,则无法有效的解决。

2. 把图片以附件的方式发送出去,这种方式非常适用于图片存在于数据库中的情况。
本文也主要讨论这种情况。

对于Java Mail的基础知识,请看http://www.yesky.com/SoftChannel/72348977504190464/20020713/1620276.shtml,
本文不作介绍了。

说到邮件中的附件,我不得不说一说MiniMultipart类,提供了在邮件中加入附加的实现方法。
一个多部分邮件是一个内容类型(content-type)被设置为MiniMultipart的Message对象。
MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象。
我们可以用一个MimeBodyPart包含html源代码,其他的MimeBodyPart包含二进制的图片附件。

但是这里有个意外情况,我们先看MimeBodyPart的初始化代码:

MimeBodyPart mdp = new MimeBodyPart(); //新建一个存放附件的BodyPart
DataHandler dh = new DataHandler(...);
mdp.setDataHandler(dh); //给BodyPart对象设置内容为dh
其中当DataHandler初始化时需要DataSource的子类

/** from JDK Doc */
public DataHandler(DataSource ds)
Create a DataHandler instance referencing the specified DataSource.
The data exists in a byte stream form. The DataSource will provide an InputStream to access the data.
Parameters:ds - the DataSource

在JDK1.4中,DataSource是个Interface,DataSource仅有MimePartDataSource, URLDataSource, FileDataSource三个子类,
而在这三个类中没有一个能直接用二进制流(byte[])创建实例。当然我们可以把内存中的二进制流写到文件中,再让FileDataSource读进来。
但是这样会给服务器带来而外的硬盘读写,若操作频繁,会造成服务器性能下降。幸运的是我再网上发现了这么一个类,可以直接用二进制流直接创建实例。

import java.io.*;
import javax.activation.*;
public class ByteArrayDataSource implements DataSource
{
/*** Data to write. */
private byte[] _data;
/*** Content-Type. */
private String _type;

/* Create a datasource from an input stream */
public ByteArrayDataSource(InputStream is,String type)
{
_type = type;
try
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
int ch;

// XXX : must be made more efficient by
// doing buffered reads, rather than one byte reads
while ((ch = is.read()) != -1)
os.write(ch);
_data = os.toByteArray();
}
catch (IOException ioe)
{
}
}
/* Create a datasource from a byte array */
public ByteArrayDataSource(byte[] data,String type)
{
_data = data;
_type = type;
}
/* Create a datasource from a String */
public ByteArrayDataSource(String data,String type)
{
try
{
// Assumption that the string contains only ascii
// characters ! Else just pass in a charset into this
// constructor and use it in getBytes()
_data = data.getBytes("iso-8859-1");
}
catch (UnsupportedEncodingException uee)
{
}
_type = type;
}
public InputStream getInputStream()
throws IOException
{
if (_data == null)
throw new IOException("no data");
return new ByteArrayInputStream(_data);
}
public OutputStream getOutputStream()
throws IOException
{
throw new IOException("cannot do this");
}
public String getContentType()
{
return _type;
}
public String getName()
{
return "dummy";
}
}

有了上面ByteArrayDataSource类,我们就可以发送图片附件的邮件了。
{
String smtpHost = ...;
String to = ...;
String from = ...;
String name = ...;
String password = ...;
String subject = ...;
StringBuffer content = ...; // 邮件的html源代码
LinkedList attachList = ...; // 附件的list,它的element都是byte[],即图片的二进制流

Properties props = new Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props, null);

MimeMessage message;
InternetAddress[] address = {new InternetAddress(to)};

message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, address);
message.setSubject(subject);
message.setSentDate(new Date());
// 新建一个MimeMultipart对象用来存放BodyPart对象(事实上可以存放多个)
MimeMultipart mm = new MimeMultipart();
// 新建一个存放信件内容的BodyPart对象
BodyPart mdp = new MimeBodyPart();
// 给BodyPart对象设置内容和格式/编码方式
mdp.setContent(content.toString(), "text/html;charset=GBK");
// 这句很重要,千万不要忘了
mm.setSubType("related");

mm.addBodyPart(mdp);

// add the attachments
for( int i=0; i<attachList.size(); i++)
{
// 新建一个存放附件的BodyPart
mdp = new MimeBodyPart();
DataHandler dh = new DataHandler(new ByteArrayDataSource((byte[])attachList.get(i),"application/octet-stream"));
mdp.setDataHandler(dh);
// 加上这句将作为附件发送,否则将作为信件的文本内容
mdp.setFileName(new Integer(i).toString() + ".jpg");
mdp.setHeader("Content-ID", "IMG" + new Integer(i).toString());
// 将含有附件的BodyPart加入到MimeMultipart对象中
mm.addBodyPart(mdp);
}
// 把mm作为消息对象的内容
message.setContent(mm);

message.saveChanges();
javax.mail.Transport transport = session.getTransport("smtp");
transport.connect(smtpHost, name, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}

在上述代码中需注意的是这句代码:
mdp.setHeader("Content-ID", "IMG" + new Integer(i).toString());
它描述了附件图片的相对路径,
当i=1时,代码就是mdp.setHeader("Content-ID", "IMG1");

我们的html源代码中,也就是上述的content中,需包含
<td align='center' valign='middle'>
<div align="center">
<a href="http://www.test.com" target="_blank" >
<img src="cid:IMG1" width="60" height="45" border="0">
</a>
</div>
</td>
就能在邮件中显示图片。 
 

linux发送html格式邮件,邮箱收不到html格式问题

问题:  在使用linux进行邮件发送时,有时候希望发送html格式的邮件,如果发现发送的html格式邮件,可是邮箱里收到的还是纯txt格式的内容。 原因: linux使用mail函数发...
  • chengfei112233
  • chengfei112233
  • 2012年02月23日 17:47
  • 6533

javamail发送文本邮件、HTML邮件及带附件邮件

MailInfo.javaimport java.util.Properties; public class MailInfo { private String mailServerHost;//...
  • oyzl68
  • oyzl68
  • 2012年11月30日 21:52
  • 16871

mail命令发送html格式的电子邮件

如果没有mail命令,使用yum安装: #yum install -y mailx 要发送html格式邮件,关键是在邮件头部指定内容格式,如下: $mail -s "$(echo -e "sub...
  • yuxiangji
  • yuxiangji
  • 2014年03月25日 15:56
  • 4350

用java实现发送html格式的邮件

import javax.mail.internet.InternetAddress;  import javax.mail.internet.MimeMessage;  import j...
  • mobile18611667978
  • mobile18611667978
  • 2017年04月14日 10:08
  • 733

spring简单邮件发送(文本/html/图片/附件)

Spring邮件抽象层的主要包为org.springframework.mail。它包括了发送电子邮件的主要接口MailSender,和值对象SimpleMailMessage,它封装了简单邮件的属性...
  • johnjobs
  • johnjobs
  • 2014年12月26日 10:31
  • 2338

Spring发送html邮件

本文基于Spring MVC 注解,让Spring跑起来。         容器:tomcat6         (1) 导入jar包mail.jar、activation.jar和org.spr...
  • geloin
  • geloin
  • 2012年05月08日 17:57
  • 8449

PHP的mail()函数发送邮件,其中的html标签未被正常解析的问题

问题描述最近有一台线上服务器迁移到了欧洲节点,操作系统和应用环境与之前都是一样,Centos6.5,PHP5.5,但是使用PHP自带的mail函数发送邮件,其中的html标签未被解析,被当成字符串直接...
  • downing114
  • downing114
  • 2017年04月05日 11:41
  • 824

Spring 4发送HTML/纯文本邮件并携带附件

原文链接:http://www.codeweblog.com/spring-4%E5%8F%91%E9%80%81html-%E7%BA%AF%E6%96%87%E4%BB%B6%E9%82%AE%E...
  • nimeijian
  • nimeijian
  • 2016年08月02日 18:57
  • 1248

java 发送html格式邮件 样式混乱解决

今天发送html格式的邮件 在qq 163 邮箱接收的时候老是样式混乱里面掺杂了 邮箱本身自己的样式 多次要前台人员帮忙调试 发现就是无法控制 然后在混乱中。。。。。。。。。。。。...
  • lei278975868
  • lei278975868
  • 2016年01月15日 14:17
  • 490

JavaMail发送HTML邮件

目的在一些客户响应系统中,面对客户的需求,我们有可能需要通过邮件对客户进行通知或者向客户反馈查询信息。比如:银行的账单系统,需要对客户的查账请求进行处理,发送账单邮件,此时就能将账单数据写入到HTML...
  • qq_24448899
  • qq_24448899
  • 2017年08月09日 08:55
  • 1093
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用Java Mail发送带有图片附件的html格式邮件
举报原因:
原因补充:

(最多只允许输入30个字)