javamail 发送邮件,发复杂html,包括附件,以及内嵌图片的邮件

当前版本:javamail1_4_4.zip      可以去oracle去下载最新的版本

发复杂的邮件,html内容,包括带附件的,邮件内容嵌入图片的邮件

首先,要导入的包有:

dsn.jar

mailapi.jar

smtp.jar

然后,直接看类

——————————————————————————————————————————————————————————

SendMail.java

package javamail;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
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;
/**
 * 
 * @author javalzbin
 *
 */
public class SendMail {
	  
	private  String smtp="";		//邮件服务器主机名
	private  String protocol="";		//邮件传输协议
	private  String username="";		//登录用户名
	private  String password="";		//登录密码
	private  String from="";		//发件人地址
	private  String to="";			//收件人地址
	private  String subject="";		//邮件主题
	private  String body="";		//邮件内容
	
	//一个有规则的map,用作嵌入图片
	Map map;
	//存放附件
	List list;
	
	
	public SendMail(Map map,List filelist,Map image){
		this.smtp=map.get("smtp");
		this.protocol=map.get("protocol");
		this.username=map.get("username");
		this.password=map.get("password");
		this.from=map.get("from");
		this.to=map.get("to");
		this.subject=map.get("subject");
		this.body=map.get("body");

		this.list=filelist;
		this.map=image;
	}

	public void send()throws Exception{
		Properties pros=new Properties();
		pros.setProperty("mail.transport.protocol", this.protocol);
		pros.setProperty("mail.host", this.smtp);
		pros.put("mail.smtp.auth", "true");
		MySendMailAuthenticator ma=new MySendMailAuthenticator(this.username,this.password);
		Session session=Session.getInstance(pros,ma);
		session.setDebug(false);
		
		MimeMessage msg=createMessage(session);
		
		Transport ts=session.getTransport();
		ts.connect();
		ts.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
		ts.close();
	}
	
	public MimeMessage createMessage(Session session)throws Exception{
		
		MimeMessage message=new MimeMessage(session);
		message.setFrom(new InternetAddress(this.from));
		message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
		message.setSubject(this.subject);
		
		MimeMultipart allMultipart=new MimeMultipart();
		
		//创建代表邮件正文和附件的各个MimeBodyPart对象
		MimeBodyPart contentpart=createContent(this.body);
		allMultipart.addBodyPart(contentpart);
		
		
		//创建用于组合邮件正文和附件的MimeMultipart对象
		for(int i=0;i0) {
			 Set> set=map.entrySet();
			 for (Iterator iterator = set.iterator(); iterator.hasNext();) {
				Entry entry = (Entry) iterator.next();
				
				//创建用于保存图片的MimeBodyPart对象,并将它保存到MimeMultipart中
				MimeBodyPart gifBodyPart=new MimeBodyPart();
				FileDataSource fds=new FileDataSource(entry.getValue());//图片所在的目录的绝对路径
				
				gifBodyPart.setDataHandler(new DataHandler(fds));
				gifBodyPart.setContentID(entry.getKey());	//cid的值
				contentMultipart.addBodyPart(gifBodyPart);
			}
		}
		
		//将MimeMultipart对象保存到MimeBodyPart对象
		contentPart.setContent(contentMultipart);
		return contentPart;
	}
	
	public MimeBodyPart createAttachment(String filename)throws Exception {
		//创建保存附件的MimeBodyPart对象,并加入附件内容和相应的信息
		MimeBodyPart attachPart=new MimeBodyPart();
		FileDataSource fsd=new FileDataSource(filename);
		attachPart.setDataHandler(new DataHandler(fsd));
		attachPart.setFileName(fsd.getName());
		return attachPart;
	}
	
}
//向邮件服务器提交认证信息
class MySendMailAuthenticator extends Authenticator{
	String username="";
	String password="";
	public MySendMailAuthenticator(String user,String pass){
		this.username=user;
		this.password=pass;
	}
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(username,password);
	}
}


接下来,如何调用:

Test.java

package javamail;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

	public static void main(String[] args)throws Exception {
		String content="点击进入百度
" + "

" + ""; Map map=new HashMap(); //邮件服务器主机名(smtp服务器地址) //如:qq的smtp服务器地址:smtp.qq.com map.put("smtp", "smtp.qq.com"); //邮件传输协议:如smtp map.put("protocol", "smtp"); //登录邮箱的用户名 map.put("username", "492509610"); //登录邮箱的密码 map.put("password", "bugaosuni"); //发送人的帐号 map.put("from", "[email protected]"); //接收人的帐号,多个以","号隔开 map.put("to", "[email protected],[email protected]"); //邮件主题 map.put("subject", "这个是主题"); //邮件内容 map.put("body", content); //内嵌了多少张图片,如果没有,则new一个不带值的Map Map image=new HashMap(); image.put("a00000001", "D:/asdf.jpg"); image.put("a00000002", "D:/中文.jpg"); //附件的绝对路径,不发附件则new一个不带值的List List list=new ArrayList(); list.add("D:/ccc.sql"); list.add("D:/Dom4j.xml"); //创建实例 SendMail sm=new SendMail(map,list,image); //执行发送 sm.send(); } }


SendMail.java我就不解释了,重点我也写了注释,需要的直接拿来用就可以了,关键是调用,我解释下test.java

conten是html内容,那么,如果需要在html内容中内嵌图片,最好不要采用在邮件正文中引用外部资源的方式,而是需要把图片文件内容当作邮件的内嵌资源处理,即把资源文件的内容和引用它的html邮件正文放在同一封邮件数据中,并将它们组合成MIME组合消息。

超链接标签中的“cid:a00000001”,表示引用MIME消息中Content-ID属性值为a00000001的消息体数据。

这个测试要嵌入两个图片,那么,有两个标签元素,对应者,image对象中,设置了两个图片的路径,其中,key则对应着img标签的cid属性值

如,上面的html中

a00000001\">

a00000002\">

那么,在image对象中,必然要对应着两条数据

image.put("a00000001", "D:/asdf.jpg");
image.put("a00000002", "D:/中文.jpg");

其中key,则对应着cid的值,value则是图片的绝对路径,如果有多个图片,那么image对象就有多条数据

然后的话 ,list 则是附件集合,一条数据就是一个文件的绝对路径,不带附件,那么是无数据的list,注意,无数据不是null,基于SendMail.java的判断,如果不带附件也没有嵌入图片,那么也需要这两个对象的实例,只是这两个实例都没有数据,即,SendMail sm=new SendMail(map,new ArrayList(),new HashMap());


来看下效果:发到qq邮箱跟163邮箱,你会发现有些小不同

首先来看下QQ邮箱收到的效果:


显示正常,两个附件,两个内嵌的图片

再来看看163的效果


太长了,截不完,不过看的出不同的在哪了,163的附件,显示4个,其实它把内嵌的两个图片当作附件处理了,当然,内容显示的也是正常的,这个不妨碍,其实重点是在时间,我在代码中,没有设置发送时间,所以可以看到,163跟QQ解释的时间也不一样,QQ是以UFC+0时区显示的,163显示的是中国时区,至于哪个比较好,这个见仁见智了,我个人觉得QQ做的比较好,那么,要想以中国的时区作为发送时间,那必须设置发送时间,看下面代码

SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);   
fm.setTimeZone(TimeZone.getTimeZone("GMT+8"));   
String moditime=fm.format(new Date());
message.setSentDate(new Date(Timestamp.valueOf(moditime).getTime()));


setSentDate 是设置发送时间的意思,以上代码加到createMessage方法里的MimeMessage message=new MimeMessage(session);代码之后message.saveChanges();之前就可以了,这样,在QQ邮箱里的结果就跟163一样了,没什么其他大问题,有问题留言,

转载保留原创:http://blog.csdn.net/javalzbin/article/details/7044907


你可能感兴趣的:(Java,Web)