发送邮件【文本-html】【图片】【邮件】【附件】
依赖
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.activation/activation -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
package com.rjj.demo.tools.mail; import com.jfinal.log.Log; import com.sun.mail.util.MailSSLSocketFactory; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.*; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.Security; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; /** ** 邮件 * * 1.普通文本 sendText html消息 sendHtml * * 2.图片 * * 3.附件 sendFile * * 4.文本+图片 sendTextPhoto * * 5.图片文本附件 sendTextPhotoFile * * 6.抄送,密送 * * 7.群发【普通发送的时候把发送地址拼接字符串a,b.c】 */ public class MailUtilMe { private Log logger = Log.getLog(MailUtil.class); //发件箱 private String fromEmail = "215060580@qq.com"; //发件箱别名 private String personel = "淡淡人生过"; //发件箱密码 private String password = "rylihxxxxxxzcajb"; //端口 private String port = "465"; //主机地址 private String host = "smtp.qq.com"; //收件人邮箱 private String toEmail = "253481340@qq.com"; //主题 private String subject ="淡淡人生过的第一份邮件"; //获取基本配置,这种可能会报错 /** * 会报错javax.net.ssl.SSLHandshakeException: * sun.security.validator.ValidatorException: * PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: * unable to find valid certification path to requested target * * 错误很简单,就是证书路径无效,网上有人说使用代码下载证书到本地jre证书库中, * 或者直接导入此证书到jre证书;确实可以;但是我们可以在代码中信任此站点证书 * @return */ public Properties getProperties(){ Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; Properties props = System.getProperties(); props.setProperty("mail.host", host);//主机 props.put("mail.transport.protocol", "smtp");//链接协议 props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY); props.setProperty("mail.smtp.socketFactory.fallback", "false"); props.setProperty("mail.smtp.port", port); props.setProperty("mail.smtp.socketFactory.port", port); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable","true");//开启ssl加密 props.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息 return props; } /** * 基本不会出现问题 * @return */ public Properties getProp(){ Properties props = System.getProperties(); props.setProperty("mail.host", host);//主机地址 props.put("mail.transport.protocol", "smtp");//链接协议 props.setProperty("mail.smtp.port", port);//端口 props.put("mail.smtp.auth", "true"); // 允许smtp校验 MailSSLSocketFactory sf = null; try { sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); } catch (GeneralSecurityException e) { logger.info("error", e); } props.put("mail.smtp.ssl.enable", "true");//开启ssl加密 props.put("mail.smtp.ssl.socketFactory", sf); props.put("mail.smtp.socketFactory.fallback", "false"); props.put("mail.smtp.socketFactory.port", port); props.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息 return props; } /** * 获取session */ public Session getSession(){ Properties prop = getProp(); Session session = Session.getDefaultInstance(prop, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(fromEmail,password); } }); return session; } public MimeMessage getMineMessage() { Session session = getSession(); // 创建默认的 MimeMessage 对象 MimeMessage message = new MimeMessage(session); try { // Set From: 头部头字段,设置了默认名称,就会显示发送人为 "淡淡人生过" message.setFrom(new InternetAddress(fromEmail,personel)); /** * Set To: 头部头字段 * * Message.RecipientType.TO 普通发送 * Message.RecipientType.CC 抄送 * Message.RecipientType.BCC 密送 */ //给一个人发送邮件 message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail)); //给多个人发送邮件 //message.addRecipients(Message.RecipientType.TO,new Address[]{new InternetAddress(toEmail),new InternetAddress(toEmail)}); //message.addRecipients(Message.RecipientType.CC,new Address[]{new InternetAddress(toEmail)}); //message.addRecipients(Message.RecipientType.BCC,new Address[]{new InternetAddress(toEmail)}); // Set Subject: 头部头字段 message.setSubject(subject,"UTF-8"); //设置邮件的发送时间 message.setSentDate(new Date()); } catch (MessagingException e) { logger.info("1出现异常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { logger.info("2出现异常:" + e.getMessage()); } return message; } /** * 发送邮件 * * 普通文本消息 */ public void sendText(String content) { MimeMessage message = getMineMessage(); // 设置消息体 try { message.setText(content); Transport.send(message); } catch (MessagingException e) { logger.info("设置文本内容出现异常:" + e.getMessage()); } } /** * 发送邮件 * * html消息 */ public void sendHtml(String content){ MimeMessage message = getMineMessage(); try { message.setContent(content,"text/html;charset=UTF-8"); Transport.send(message); } catch (MessagingException e) { logger.info("设置html内容出现异常:" + e.getMessage()); } } /** * 发送带附件的邮件 */ public void sendFile(String content, String pathFileName){ MimeMessage message = getMineMessage(); // 创建多重消息 Multipart multipart = new MimeMultipart(); try { // 创建消息部分 BodyPart messageBodyPart = new MimeBodyPart(); // 消息,这里的消息不发送也是可以的 // messageBodyPart.setText(content); messageBodyPart.setContent(content, "text/html; charset=utf-8"); // 设置文本消息部分 multipart.addBodyPart(messageBodyPart); // 附件部分 messageBodyPart = new MimeBodyPart(); //获取文件 DataSource source = new FileDataSource(pathFileName); messageBodyPart.setDataHandler(new DataHandler(source)); //设置文件名称 messageBodyPart.setFileName(MimeUtility.encodeText(source.getName())); //添加到多重消息容器中 multipart.addBodyPart(messageBodyPart); // 发送完整消息 message.setContent(multipart); // 发送消息 Transport.send(message); } catch (MessagingException e) { logger.info("发送附件邮件出现异常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { logger.info("文件名称编码异常:" + e.getMessage()); } } /** * 多文件下载 * @param content 信息 * @param pathFileName 多个附件的路径 */ public void sendFileList(String content, List<String> pathFileName){ MimeMessage message = getMineMessage(); try { // 创建多重消息 Multipart multipart = new MimeMultipart(); //消息 BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(content,"text/html; charset=utf-8"); multipart.addBodyPart(messageBodyPart); for (String filePath : pathFileName) { // 附件部分 // 创建消息部分 messageBodyPart = new MimeBodyPart(); //获取文件 DataSource source = new FileDataSource(filePath); messageBodyPart.setDataHandler(new DataHandler(source)); //设置文件名称 messageBodyPart.setFileName(MimeUtility.encodeText(source.getName())); //添加到多重消息容器中 multipart.addBodyPart(messageBodyPart); } // 发送完整消息 message.setContent(multipart); // 发送消息 Transport.send(message); } catch (MessagingException e) { logger.info("发送附件邮件出现异常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { logger.info("文件名称编码异常:" + e.getMessage()); } } /** * 发送图片和附件邮件 */ public void sendTextPhotoFile(){ String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg"; MimeMessage message = getMineMessage(); try { // 1.创建图片"节点" MimeBodyPart image = new MimeBodyPart(); // 读取本地文件 DataHandler dh = new DataHandler(new FileDataSource(pathName)); // 将图片数据添加到"节点" image.setDataHandler(dh); // 为"节点"设置一个唯一编号(在文本"节点"将引用该ID) image.setContentID("mailTestPic"); // 2. 创建文本"节点" MimeBodyPart text = new MimeBodyPart(); // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片 /** * 这里在img标签中src属性中添加了cid:mailTestPic 其实就是把图片和我发送的图片关联起来了,点击图片就会跳到我的路径所在的地址 这里使用a标签包裹了,我的图片,发送的内容其实时html的,所以有些标签不显示,其实一html的标签 */ text.setContent( "这是一张图片<br/><a href='http://www.cnblogs.com/ysocean/p/7666061.html'>" + //我想要点击图片跳到的地址 "<img src='cid:mailTestPic'/>" + //图片,可以写网络图片的地址 "</a>" , "text/html;charset=UTF-8");//html,使用utf-8,识别 // 3. (文本+图片)设置 文本 和 图片"节点"的关系(将 文本 和 图片"节点"合成一个混合"节点") MimeMultipart mm_text_image = new MimeMultipart(); mm_text_image.addBodyPart(text); mm_text_image.addBodyPart(image); mm_text_image.setSubType("related"); // 关联关系 // 4. 将 文本+图片 的混合"节点"封装成一个普通"节点" // 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart, // 上面的 mailTestPic 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart MimeBodyPart text_image = new MimeBodyPart(); text_image.setContent(mm_text_image); // 5. 创建附件"节点" MimeBodyPart attachment = new MimeBodyPart(); // 读取本地文件 DataHandler dh2 = new DataHandler(new FileDataSource(pathName)); // 将附件数据添加到"节点" attachment.setDataHandler(dh2); // 设置附件的文件名(需要编码) attachment.setFileName(MimeUtility.encodeText(dh2.getName())); // 6. 设置(文本+图片)和 附件 的关系(合成一个大的混合"节点" / Multipart ) MimeMultipart mm = new MimeMultipart(); mm.addBodyPart(text_image); mm.addBodyPart(attachment); // 如果有多个附件,可以创建多个多次添加 mm.setSubType("mixed"); // 混合关系 // 7. 设置整个邮件的关系(将最终的混合"节点"作为邮件的内容添加到邮件对象) message.setContent(mm); Transport.send(message); } catch (MessagingException e) { logger.info("图片文本文件消息异常:" + e.getMessage()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } public void sendTextPhoto(){ String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg"; MimeMessage message = getMineMessage(); try { // 1.创建图片"节点" MimeBodyPart image = new MimeBodyPart(); // 读取本地文件 DataHandler dh = new DataHandler(new FileDataSource(pathName)); // 将图片数据添加到"节点" image.setDataHandler(dh); // 为"节点"设置一个唯一编号(在文本"节点"将引用该ID) image.setContentID("mailTestPic"); // 2. 创建文本"节点" MimeBodyPart text = new MimeBodyPart(); // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片 /** * 这里在img标签中src属性中添加了cid:mailTestPic 其实就是把图片和我发送的图片关联起来了,点击图片就会跳到我的路径所在的地址 这里使用a标签包裹了,我的图片,发送的内容其实时html的,所以有些标签不显示,其实一html的标签 */ text.setContent( "这是一张图片<br/><a href='http://www.cnblogs.com/ysocean/p/7666061.html'>" + //我想要点击图片跳到的地址 "<img src='cid:mailTestPic'/>" + //图片,可以写网络图片的地址 "</a>" , "text/html;charset=UTF-8");//html,使用utf-8,识别 // 3. (文本+图片)设置 文本 和 图片"节点"的关系(将 文本 和 图片"节点"合成一个混合"节点") MimeMultipart mm_text_image = new MimeMultipart(); mm_text_image.addBodyPart(text); mm_text_image.addBodyPart(image); /** * 邮件体包含邮件的内容,它的类型由邮件头的“Content-Type”域指出。常见的简单类型有text/plain(纯文本)和text/html(超文本)。有时也会出现的multipart类型,是MIME邮件的精髓。邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。常见的multipart类型有三种:multipart/mixed, multipart/related和multipart/alternative。 * * multipart/mixed:附件。 * * multipart/related:内嵌资源。 * * multipart/alternative:纯文本与超文本共存。 */ mm_text_image.setSubType("mixed"); // 关联关系,这里图片相当于附件了,只是在正文内容中一img标签显示出来了 // 7. 设置整个邮件的关系(将最终的混合"节点"作为邮件的内容添加到邮件对象) message.setContent(mm_text_image); Transport.send(message); } catch (MessagingException e) { logger.info("发送文本图片消息出现异常:" + e.getMessage()); } } public static void main(String[] args) { String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg"; MailUtilMe m = new MailUtilMe(); //m.sendTextPhotoFile(); //m.sendText("a"); //m.sendHtml("<b>你好</b>"); // m.sendFile("刘亦菲哦",pathName); // m.sendTextPhoto(); List<String> list = new ArrayList<>(2); list.add("/Users/renjianjun/study/ideaWorkSpace/demo/src/main/resources/static/img/lyf.jpg"); list.add("/Users/renjianjun/study/ideaWorkSpace/demo/src/main/resources/static/img/lyf.jpg"); m.sendFileList("刘亦菲",list); } }