之前自己这边是有一个sendmail的组件,但是只能实现text的发送,今天逛博客,无意间发现了一个能够实现发送附件的senfmail功能的java实现,于是就进行了测试和实现,经过测试能够成功实现附件功能,希望通过发博的方式进行收藏,也把中间出现 的问题和大家进行分享:
1.首先在Mail工程下新建lib文件夹,导入javax.mail.jar包;
2.在Mail项目下新建conf文件夹,新建file:mail-info.properties,进行配置;
1 mail.host=smtp.126.com 2 mail.port=25 3 mail.username=zhanglincumt@126.com 4 mail.password=****** 5 mail.from=zhanglincumt@126.com 6 mail.to=1447363383@qq.comView Code
3.新建一个util的package,里面放读取配置文件的AppContext.java和保存临时配置文件的SystemContains.java;
1 package util; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Properties; 6 /** 7 * 读取配置文件 8 * 2014年12月31日 9 */ 10 public enum AppContext { 11 12 INSTANCE; 13 14 public Properties configuration = new Properties(); 15 16 public void init() { 17 InputStream is = this.getClass().getResourceAsStream("/mail-info.properties"); 18 if (is != null) { 19 try { 20 this.configuration.clear(); 21 this.configuration.load(is); 22 } catch (IOException e) { 23 } finally { 24 try { 25 is.close(); 26 } catch (Throwable t) {} 27 } 28 } 29 } 30 31 public String getConfigValue(String key) { 32 return this.configuration.getProperty(key); 33 } 34 35 }View Code
1 package util; 2 /** 3 * 临时保存配置文件信息 4 */ 5 public class SystemConstants { 6 //info 7 public static final String MAILHOST = AppContext.INSTANCE.getConfigValue("mail.host"); 8 public static final String MAILPORT = AppContext.INSTANCE.getConfigValue("mail.port"); 9 public static final String MAILUSERNAME = AppContext.INSTANCE.getConfigValue("mail.username"); 10 public static final String MAILPASSWORD = AppContext.INSTANCE.getConfigValue("mail.password"); 11 public static final String MAILFROM = AppContext.INSTANCE.getConfigValue("mail.from"); 12 public static final String MAILTO = AppContext.INSTANCE.getConfigValue("mail.to"); 13 }View Code
4.在mail包下新建发送文件类JavaMail.java和压缩解压缩类ZIP.java;
1 package mail; 2 3 import java.io.File; 4 5 import javax.activation.DataHandler; 6 import javax.activation.DataSource; 7 import javax.activation.FileDataSource; 8 import javax.mail.Address; 9 import javax.mail.BodyPart; 10 import javax.mail.Message; 11 import javax.mail.MessagingException; 12 import javax.mail.Multipart; 13 import javax.mail.Session; 14 import javax.mail.Transport; 15 import javax.mail.internet.InternetAddress; 16 import javax.mail.internet.MimeBodyPart; 17 import javax.mail.internet.MimeMessage; 18 import javax.mail.internet.MimeMultipart; 19 import javax.mail.internet.MimeUtility; 20 21 import util.AppContext; 22 import util.SystemConstants; 23 /** 24 * send email 25 * 2014年12月31日 26 */ 27 28 public class JavaMail { 29 /** 30 * Message对象将存储我们实际发送的电子邮件信息, 31 * Message对象被作为一个MimeMessage对象来创建并且需要知道应当选择哪一个JavaMail session。 32 */ 33 private MimeMessage message; 34 35 /** 36 * Session类代表JavaMail中的一个邮件会话。 37 * 每一个基于JavaMail的应用程序至少有一个Session(可以有任意多的Session)。 38 * 39 * JavaMail需要Properties来创建一个session对象。 40 * 寻找"mail.smtp.host" 属性值就是发送邮件的主机 41 * 寻找"mail.smtp.auth" 身份验证,目前免费邮件服务器都需要这一项 42 */ 43 private Session session; 44 45 /*** 46 * 邮件是既可以被发送也可以被受到。JavaMail使用了两个不同的类来完成这两个功能:Transport 和 Store。 47 * Transport 是用来发送信息的,而Store用来收信。对于这的教程我们只需要用到Transport对象。 48 */ 49 private Transport transport; 50 51 /* 52 * 初始化方法 53 */ 54 public JavaMail(boolean debug) { 55 session = Session.getInstance(AppContext.INSTANCE.configuration); 56 session.setDebug(debug);//开启后有调试信息 57 message = new MimeMessage(session); 58 } 59 60 /** 61 * 发送邮件 62 * @param subject 邮件主题 63 * @param sendHtml 邮件内容 64 */ 65 public void sendEmail(String subject, String sendHtml) { 66 try { 67 // 发件人 68 //InternetAddress from = new InternetAddress(sender_username); 69 // 下面这个是设置发送人的Nick name 70 InternetAddress from = new InternetAddress(MimeUtility.encodeWord("zhanglincc")+" <"+SystemConstants.MAILUSERNAME+">"); 71 message.setFrom(from); 72 73 // 收件人 74 InternetAddress to = new InternetAddress(SystemConstants.MAILTO); 75 message.setRecipient(Message.RecipientType.TO, to);//还可以有CC、BCC 76 77 // 邮件主题 78 message.setSubject(subject); 79 80 String content = sendHtml.toString(); 81 82 // 邮件内容,也可以使纯文本"text/plain" 83 message.setContent(content, "text/html;charset=UTF-8"); 84 85 // 保存邮件 86 message.saveChanges(); 87 88 // smtp验证,就是你用来发邮件的邮箱用户名密码 89 transport = session.getTransport("smtp"); 90 transport.connect(SystemConstants.MAILHOST, SystemConstants.MAILUSERNAME, SystemConstants.MAILPASSWORD); 91 92 // 发送 93 transport.sendMessage(message, message.getAllRecipients()); 94 95 System.out.println("send success!"); 96 } catch (Exception e) { 97 e.printStackTrace(); 98 }finally { 99 if(transport!=null){ 100 try { 101 transport.close(); 102 } catch (MessagingException e) { 103 e.printStackTrace(); 104 } 105 } 106 } 107 } 108 109 /** 110 * 发送邮件 111 * @param subject 邮件主题 112 * @param sendHtml 邮件内容 113 * @param attachment 附件 114 */ 115 public void sendEmail(String subject, String sendHtml, String filePath) { 116 File file = new File(filePath); 117 if(file.exists()){ 118 try { 119 // 发件人 120 InternetAddress from = new InternetAddress(SystemConstants.MAILUSERNAME); 121 message.setFrom(from); 122 123 String [] strings = SystemConstants.MAILTO.split(";"); 124 Address [] receiverAddress = new Address[strings.length]; 125 126 for(int i = 0;i<strings.length;i++){ 127 receiverAddress[i]=new InternetAddress(strings[i]); 128 } 129 130 message.setRecipients(Message.RecipientType.TO, receiverAddress); 131 132 // 邮件主题 133 message.setSubject(subject); 134 135 // 向multipart对象中添加邮件的各个部分内容,包括文本内容和附件 136 Multipart multipart = new MimeMultipart(); 137 138 // 添加邮件正文 139 BodyPart contentPart = new MimeBodyPart(); 140 contentPart.setContent(sendHtml, "text/html;charset=UTF-8"); 141 multipart.addBodyPart(contentPart); 142 143 //如果所给的路径是目录就压缩 144 if(file.isDirectory()){ 145 File fileTemp = new File(file.getParentFile().getAbsoluteFile()+"//"+file.getName()+".zip"); 146 System.out.println(fileTemp.getAbsolutePath()); 147 ZIP.zipFiles(file.listFiles(),fileTemp); 148 file = fileTemp; 149 System.out.println(file.isFile()); 150 } 151 // 添加附件的内容 152 if (file.isFile()) { 153 BodyPart attachmentBodyPart = new MimeBodyPart(); 154 DataSource source = new FileDataSource(file); 155 attachmentBodyPart.setDataHandler(new DataHandler(source)); 156 157 // 网上流传的解决文件名乱码的方法,其实用MimeUtility.encodeWord就可以很方便的搞定 158 // 这里很重要,通过下面的Base64编码的转换可以保证你的中文附件标题名在发送时不会变成乱码 159 //sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder(); 160 //messageBodyPart.setFileName("=?GBK?B?" + enc.encode(attachment.getName().getBytes()) + "?="); 161 162 //MimeUtility.encodeWord可以避免文件名乱码 163 attachmentBodyPart.setFileName(MimeUtility.encodeWord(file.getName())); 164 multipart.addBodyPart(attachmentBodyPart); 165 } 166 167 // 将multipart对象放到message中 168 message.setContent(multipart); 169 // 保存邮件 170 message.saveChanges(); 171 172 transport = session.getTransport("smtp"); 173 // smtp验证,就是你用来发邮件的邮箱用户名密码 174 transport.connect(SystemConstants.MAILHOST, SystemConstants.MAILUSERNAME, SystemConstants.MAILPASSWORD); 175 // 发送 176 transport.sendMessage(message, message.getAllRecipients()); 177 178 System.out.println("send success!"); 179 } catch (Exception e) { 180 e.printStackTrace(); 181 } finally { 182 if (transport != null) { 183 try { 184 transport.close(); 185 } catch (MessagingException e) { 186 e.printStackTrace(); 187 } 188 } 189 } 190 }else{ 191 System.out.println("附件地址有误 "); 192 System.exit(-1); 193 } 194 } 195 196 }View Code
1 package mail; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.OutputStream; 9 import java.util.Enumeration; 10 import java.util.zip.ZipEntry; 11 import java.util.zip.ZipFile; 12 import java.util.zip.ZipOutputStream; 13 14 /** 15 * 压缩文件、解压压缩文件 16 * 2014年12月31日 17 */ 18 public class ZIP { 19 20 /** 21 * 功能:压缩多个文件成一个zip文件 22 * @param srcfile:源文件列表 23 * @param zipfile:压缩后的文件 24 */ 25 public static void zipFiles(File[] srcfile, File zipfile) { 26 byte[] buf = new byte[1024]; 27 try { 28 // ZipOutputStream类:完成文件或文件夹的压缩 29 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile)); 30 for (int i = 0; i < srcfile.length; i++) { 31 FileInputStream in = new FileInputStream(srcfile[i]); 32 out.putNextEntry(new ZipEntry(srcfile[i].getName())); 33 int len; 34 while ((len = in.read(buf)) > 0) { 35 out.write(buf, 0, len); 36 } 37 out.closeEntry(); 38 in.close(); 39 } 40 out.close(); 41 System.out.println("压缩完成."); 42 } catch (Exception e) { 43 e.printStackTrace(); 44 } 45 } 46 47 /** 48 * 功能:解压缩 49 * @param zipfile:需要解压缩的文件 50 * @param descDir:解压后的目标目录 51 * @throws IOException 52 */ 53 @SuppressWarnings("rawtypes") 54 public static void unZipFiles(File zipfile, String descDir) { 55 File file = new File(descDir); 56 if (!file.exists()) { 57 try { 58 file.mkdir(); 59 } catch (Exception e) { 60 e.printStackTrace(); 61 } 62 } 63 try { 64 ZipFile zf = new ZipFile(zipfile); 65 for (Enumeration entries = zf.entries(); entries.hasMoreElements();) { 66 ZipEntry entry = (ZipEntry) entries.nextElement(); 67 String zipEntryName = entry.getName(); 68 InputStream in = zf.getInputStream(entry); 69 OutputStream out = new FileOutputStream(descDir + zipEntryName); 70 byte[] buf1 = new byte[1024]; 71 int len; 72 while ((len = in.read(buf1)) > 0) { 73 out.write(buf1, 0, len); 74 } 75 in.close(); 76 out.close(); 77 System.out.println("解压缩完成."); 78 } 79 80 zf.close(); 81 } catch (Exception e) { 82 e.printStackTrace(); 83 } 84 } 85 86 public static void main(String[] args) { 87 // 需要解压缩的文件 88 File file = new File("D://test"); 89 File filenew = new File("D://test.zip"); 90 zipFiles(file.listFiles(), filenew); 91 92 // 解压后的目标目录 93 String dir = "D://workspace//"; 94 unZipFiles(filenew, dir); 95 } 96 }View Code
5.新建测试类进行测试;
1 package main; 2 3 import util.AppContext; 4 import mail.JavaMail; 5 6 public class Main { 7 public static void main(String[] args) { 8 AppContext.INSTANCE.init(); 9 JavaMail mail = new JavaMail(false); 10 mail.sendEmail("来自lynnzhangcc的邮件", "我是邮件内容"); 11 mail.sendEmail("测试附件为文件夹的邮件主题", "测试附件为文件夹的邮件内容","D://test"); 12 mail.sendEmail("测试附件为文件的邮件主题", "测试附件文件的邮件内容","D://test"); 13 } 14 }View Code
如果运行正常,console会打印send success!的语句。
运行过程中可能会出现以下异常:
1.java运行和编译版本冲突
该异常表明java编译和运行的jdk版本不同,可能是你进行项目位置更改发生的异常,解决办法如下:
右键点击项目Mail,选择properties
该问题就能解决。
2.身份验证异常;
该问题一般是身份验证未通过,只要在mail-info.properties配置中,不要使用申请时间不长的邮箱就可以解决。