用户名: 密码: [免费注册] [忘记密码]
您的位置:首页 -- jsp技术
Java Mail发送带有图片的html格式的邮件
发布日期:2012-12-12     返回

用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>
就能在邮件中显示图片。

典型客户
JAVA技术
 
域信息科技提供专业的jsp空间服务,jsp空间,jsp空间租用,jsp空间购买,虚拟JSP主机,jsp主机,独享TOMCAT,JSP服务器
售前电话:400-004-4994
售后电话:400-004-4994
技术支持(7×24支持):400-004-4994 018241839456
公司地址:阜新市中华路65号新天地大厦9F
邮编:123000       传真:0418-2493388-606
经营性ICP证:辽B-2-4-20070114    ICP备案: 辽ICP备07005704号
域信息科技提供专业的jsp空间,虚拟JSP主机,jsp主机,独享TOMCAT,JSP服务器
域信息科技提供专业的jsp空间,虚拟JSP主机,jsp主机,独享TOMCAT,JSP服务器