Java Mail是利用已存在的邮箱账号,不必登录如网易邮箱,qq邮箱等官方邮箱网站而使用程序发送邮件。这在web中很常见,比如直接在招聘网站给hr发邮件就是一个典型运用。

利用Java Mail发送邮件的大致步骤:

 

1.首先,构建一个用于登录校验的类,确保你对此邮箱账户有发送邮件的权限。(相当于登录邮箱的过程)

public class MailAuthenticator extends Authenticator {
	
	private String username;
	private String password;
	
	//带参数的构造器,初始化邮箱登录的用户名和密码
	public MailAuthenticator(String username, String password) {
//		super();
		this.username = username;
		this.password = password;
	}
	
//重写该方法,获得	PasswordAuthentication 	对象
	@Override
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(username, password);
	}



	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	
}

 

2.简单邮件类,包括主题(subject)和内容(content)。

public class SimpleMail {
	
	private String subject;
	private Object content;
	
	
	public SimpleMail(String subject, Object content) {
		super();
		this.subject = subject;
		this.content = content;
	}
	
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public Object getContent() {
		return content;
	}
	public void setContent(Object content) {
		this.content = content;
	}
	
	
}

 

 

3.发送邮件的工具类

3.1)一些必备属性 vs 邮件发送初始化(构造器)

//发送邮件的props文件
	private Properties props = System.getProperties();
	//邮件服务器的登录验证
	private MailAuthenticator authenticator;
	//邮箱发送会话
	private Session session;

        public MailSender(String username, String password) {
 
               //根据发送邮箱的账号解析出smtp服务器
		String smtpHostName = "smtp." + username.split("@")[1];
                //初始化props
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.host", smtpHostName);
		//发送验证
		authenticator = new MailAuthenticator(username,password);
		//创建邮箱收发会话的session
		session = Session.getInstance(props, authenticator);
	}

 

 

3.2)发送邮件的方法

 

情形一:简单邮件(不含附件)发送

//向一个人发送邮件
	public void send(String recipient, SimpleMail mail) throws AddressException, MessagingException {
		//根据session创建MimeMessage
		MimeMessage message = new MimeMessage(session);
		//发件人
		message.setFrom(new InternetAddress(authenticator.getUsername()));
		//收件人 
		message.setRecipient(RecipientType.TO, new InternetAddress(recipient));
		
		//主题
		message.setSubject(mail.getSubject());
		//内容
		message.setContent(mail.getContent().toString(), "text/html;charset=utf-8");
		//发送
		Transport.send(message);
	}

 

情形二:简单邮件群发

 

只需把收件人改成一个集合,但传入message的recipient应为数组

public void send(List<String> recipients, SimpleMail mail) throws MessagingException {
//.............................		
		//收件人们
		InternetAddress[] addresses = new InternetAddress[recipients.size()];
		for(int i=0; i< addresses.length; i++) {
			addresses[i] = new InternetAddress(recipients.get(i));
		}
		message.setRecipients(RecipientType.TO, addresses);
//..............................		
	}

 

情形三:带多个附件发送

 

//向一个人发送邮件(带多个附件)
		public void send(String recipient, SimpleMail mail, List<File> attachments) throws AddressException, MessagingException, UnsupportedEncodingException {
			//根据session创建MimeMessage
			MimeMessage message = new MimeMessage(session);
			//发件人
			message.setFrom(new InternetAddress(authenticator.getUsername()));
			//收件人
			message.setRecipient(RecipientType.TO, new InternetAddress(recipient));
			
			//主题
			message.setSubject(mail.getSubject());
			
			Multipart multipart = new MimeMultipart(); 
			//邮件正文
			BodyPart contentPart = new MimeBodyPart();
			contentPart.setContent(mail.getContent(), "text/html;charset=utf-8");
			multipart.addBodyPart(contentPart);
			//邮件附件
			if(attachments != null) {
				for(File attachment : attachments) {
					BodyPart attachmentPart = new MimeBodyPart();
					DataSource source = new FileDataSource(attachment);
					attachmentPart.setDataHandler(new DataHandler(source));
					//避免中文乱码的处理
					attachmentPart.setFileName(MimeUtility.encodeWord(attachment.getName()));
					multipart.addBodyPart(attachmentPart);
				}
			}
			message.setContent(multipart);
			//保存邮件
			message.saveChanges();
			Transport.send(message);
		}

 注:带一个附件的写法很简单,就是把方法的形参变为File attachment,而邮件附件里不用for循环即可。同理,带多个附件和一个附件的群发原理大致,此处省略……

 

 

方法小结:

注意带附件和不带附件的写法上的区别——不带附件的简单邮件只需用MimeMessage 对象包装即可,加上设置其subject(主题),content(内容)即可发送;而带附件的邮件对象的正文需用Multipart 包装,其中Multipart 又包括邮件内容(content)和邮件附件,这两个字部分都是用BodyPart 包装的。

 

4.遇到的问题

1)java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream

造成这个错误是由于mail.jar包里的javax.mail和javax.activation和java ee包里的javax.mail和javax.activation冲突了,只需到达myeclipse安装目录下找到java ee包里的javax.mail和javax.activation,把这两个目录删除即可——千万不要删除整个javaee.jar包!

2)javax.mail.AuthenticationFailedException: 454 Authentication failed, please open smtp flag first!

确保收发邮箱的SMTP/POP3功能已经开启!

 

5.测试类(以带多个附件的邮件发送为例)

public static void main(String[] args) {
		SimpleMailSender sender = new SimpleMailSender("xxxxx@126.com", "xxxxx");
		String subject = "这是一份测试邮件4";
		Object content = "今天天气真好啊!<br/>注:附件为一封日志文件和图片";
		SimpleMail mail = new SimpleMail(subject, content);
		try {
//			List<String> recipients = new ArrayList<String>();
//			recipients.add("xxxx@sohu.com");
//			recipients.add("xxxx@yean.net");
//			sender.send(recipients, mail);
			List<File> attaches = new ArrayList<File>();
			File attach1 = new File("C:\\Users\\xxxx\\Desktop\\log.txt");
			File attach2 = new File("C:\\Users\\xxx\\Desktop\\彩虹.jpg");
			attaches.add(attach1);
			attaches.add(attach2);
			sender.send("yyyyy@sohu.com", mail, attaches);
			System.out.println("发送成功!");
		} catch (AddressException e) {
			System.out.println("未找到接收邮箱");
			e.printStackTrace();
		} catch (MessagingException e) {
			System.out.println("发送失败"); 
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

打开接收邮箱,可看到邮件:

 

   主题:         

java 解析邮件正文中的附件 java邮件附件加密_MimeMessage

 

内容:

java 解析邮件正文中的附件 java邮件附件加密_Multipart_02


 

附件:

 

java 解析邮件正文中的附件 java邮件附件加密_JavaMail_03