代码改变世界

spring邮件发送(转)

2013-11-20 13:29  夜半花开  阅读(380)  评论(0编辑  收藏  举报
spring对邮件发送支持的很好,我们只要配置好邮件发送器,写好邮件发送具体操作类的方法,那么实现就不是很难的事,不过这个过程中经常会出现这样或那样的错误,所以待讲完本篇后我会总体总结下spring邮件发送容易发生的错误及解决办法

关于邮件发送,不外乎有这么几种情况,一种是纯文本的发送,一种是HTML形式的发送,一种就是发送时带有附件,一种就是发送时采取的事群发,针对这几个我将一一来讲下,我的代码中将第一中归为一大类,后面三种归为一代类,所以将会出现两种配置文件

第一大类邮件发送【纯文本发送】

必须包:spring.jar,common-logging.jar,mail.jar,servlet.jar,common-collection.jar

首先我们来看spring配置文件applicationContext.xml

Xml代码  收藏代码
  1. <span style="font-size: medium;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="  
  6.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  7.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  8.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  9.     <!--定义邮件发送器,配置好发送者详细信息-->  
  10.     <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">  
  11.         <property name="host" value="smtp.163.com" />  
  12.         <property name="port" value="25" />  
  13.         <property name="username" value="emailusername" />  
  14.         <property name="password" value="emailpassword" />  
  15.         <property name="defaultEncoding" value="utf-8" />  
  16.         <property name="javaMailProperties">  
  17.             <props>  
  18.                 <prop key="mail.smtp.auth">true</prop>  
  19.             </props>  
  20.         </property>  
  21.     </bean>  
  22.   
  23.     <bean id="emailService" class="com.javacrazyer.comon.SendOrderConfirmationEmailAdvice">  
  24.         <property name="mailSender" ref="mailSender" />  
  25.     </bean>  
  26.   
  27. </beans></span>  

用到的实体类Order.java

Java代码  收藏代码
  1. <span style="font-size: medium;">package com.javacrazyer.comon;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Order implements Serializable {  
  6.   
  7.     /* Private Fields */  
  8.   
  9.     private int orderId;  
  10.     private String username;  
  11.     private String useremail;  
  12.   
  13.     public int getOrderId() {  
  14.         return orderId;  
  15.     }  
  16.   
  17.     public void setOrderId(int orderId) {  
  18.         this.orderId = orderId;  
  19.     }  
  20.   
  21.     public String getUsername() {  
  22.         return username;  
  23.     }  
  24.   
  25.     public void setUsername(String username) {  
  26.         this.username = username;  
  27.     }  
  28.   
  29.     public String getUseremail() {  
  30.         return useremail;  
  31.     }  
  32.   
  33.     public void setUseremail(String useremail) {  
  34.         this.useremail = useremail;  
  35.     }  
  36.   
  37. }  
  38. </span>  

 

 邮件发送类的接口类MailService.java

Java代码  收藏代码
  1. <span style="font-size: medium;">package com.javacrazyer.comon;  
  2.   
  3.   
  4. /** 
  5.  * 使用Spring发送邮件 
  6.  *  
  7.  */  
  8.   
  9. public interface MailService {  
  10.       
  11.       
  12.     void sendOrderMail(Order order);  
  13.   
  14. }  
  15. </span>  

 

具体实现的邮件发送类SendOrderConfirmationEmailAdvice.java

Java代码  收藏代码
  1. <span style="font-size: medium;">package com.javacrazyer.comon;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6.   
  7. import org.springframework.mail.MailSender;  
  8. import org.springframework.mail.SimpleMailMessage;  
  9.   
  10. public class SendOrderConfirmationEmailAdvice implements MailService{  
  11.   
  12.     private String from="emailusername@163.com"//发送人邮箱地址,必须与spring配置文件中的邮箱地址一样  
  13.     private String registeTemplateName = "com/javacrazyer/comon/mail_registe.txt";  
  14.     private MailSender mailSender;  
  15.   
  16.     public void setMailSender(MailSender mailSender) {  
  17.         this.mailSender = mailSender;  
  18.     }  
  19.   
  20.   
  21.     public void sendOrderMail(Order order) {  
  22.         //SimpleMialMessage只能用来发送TEXT格式的邮件  
  23.         SimpleMailMessage mail = new SimpleMailMessage();  
  24.         mail.setFrom(this.from);  
  25.         mail.setTo(order.getUseremail());  
  26.         mail.setSubject("恭喜你成功注册成为SOMEDAY商城的会员!");  
  27.         mail.setText(loadTemplateContent(registeTemplateName).replaceAll("\\$\\{LOGINNAME\\}", order.getUsername()));  
  28.         this.mailSender.send(mail);  
  29.   
  30.     }  
  31.   
  32.   
  33.       
  34.     private String loadTemplateContent(String templateName){  
  35.         StringBuilder sb = new StringBuilder();  
  36.         BufferedReader br= null;  
  37.         try{  
  38.             br = new BufferedReader(  
  39.                     new InputStreamReader(  
  40.                         Thread.currentThread()  
  41.                               .getContextClassLoader()  
  42.                               .getResourceAsStream(templateName), "UTF-8"));  
  43.               
  44.             String lineSeparator = System.getProperty("line.separator");  
  45.             for(String str = null; (str = br.readLine()) != null;){  
  46.                 sb.append(str);  
  47.                 sb.append(lineSeparator);  
  48.             }  
  49.         }catch(IOException e){  
  50.             e.printStackTrace();  
  51.         }finally{  
  52.             if(br != null){  
  53.                 try {  
  54.                     br.close();  
  55.                 } catch (IOException e) {  
  56.                     e.printStackTrace();  
  57.                 }  
  58.             }  
  59.         }  
  60.           
  61.         return sb.toString();  
  62.     }  
  63.   
  64.   
  65.   
  66. }</span>  

 用到的mail_registe.txt

Java代码  收藏代码
  1. <span style="font-size: medium;">亲爱的${LOGINNAME}:您好!  
  2. 恭喜你成为SOMEDAY商城的会员!  
  3.   
  4. 你的登录用户名为:${LOGINNAME}  
  5. 你的登录口令为:******(隐藏)  
  6.   
  7. 本站网址:http://www.yoursitename.cn  
  8. 联系邮箱:hr@yoursite.cn</span>  

 

测试发送

Java代码  收藏代码
  1. <span style="font-size: medium;">package com.javacrazyer.service.test;  
  2.   
  3. import org.junit.Test;  
  4. import org.springframework.context.ApplicationContext;  
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6.   
  7. import com.javacrazyer.comon.MailService;  
  8. import com.javacrazyer.comon.Order;  
  9.   
  10. public class UserServiceTest {  
  11.   
  12.     @Test  
  13.     public void test() throws InterruptedException {  
  14.         ApplicationContext context = new ClassPathXmlApplicationContext(  
  15.                 "applicationContext.xml");  
  16.         MailService sf = (MailService) context.getBean("emailService");  
  17.         Order order = new Order();  
  18.         order.setUsername("cheneywu");  
  19.         order.setUseremail("xxxxxx@qq.com");  
  20.         sf.sendOrderMail(order);  
  21.     }  
  22. }</span>  

 注意查收邮箱中的信息哦


第二大类邮件发送【HTML格式的发送,群发,附件】

  除了上面包外,还需要spring-webmvc.jar,freemarker.jar,为什么需要freemarker呢,因为要发送HTML格式的 文件,所以要先写好HTML内容的文件,然后用模板freemarker匹配其中的值,Spring中对freemarker也有很好的支持

 spring配置文件applicatonContext-html.xml

Xml代码  收藏代码
  1. <span style="font-size: medium;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="  
  6.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  7.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  8.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  9.     <bean id="freeMarker"  
  10.         class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
  11.         <property name="templateLoaderPath" value="classpath:mailTemplate" />  
  12.         <!--指定模板文件目录-->  
  13.         <property name="freemarkerSettings"><!-- 设置FreeMarker环境属性-->  
  14.             <props>  
  15.                 <prop key="template_update_delay">1800</prop><!--刷新模板的周期,单位为秒-->  
  16.                 <prop key="default_encoding">UTF-8</prop><!--模板的编码格式 -->  
  17.                 <prop key="locale">zh_CN</prop><!-- 本地化设置-->  
  18.             </props>  
  19.         </property>  
  20.     </bean>  
  21.   
  22.     <!-- 注意:这里的参数(如用户名、密码)都是针对邮件发送者的 -->  
  23.     <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">  
  24.         <property name="host" value="smtp.163.com" />  
  25.         <property name="port" value="25" />  
  26.         <property name="username" value="emailusername" />  
  27.         <property name="password" value="emailpassword" />  
  28.         <property name="defaultEncoding" value="utf-8" />  
  29.         <property name="javaMailProperties">  
  30.             <props>  
  31.                 <prop key="mail.smtp.auth">true</prop>  
  32.             </props>  
  33.         </property>  
  34.     </bean>  
  35.     <bean id="emailService" class="com.javacrazyer.comon.EmailService">  
  36.         <property name="mailSender" ref="mailSender"></property>  
  37.         <property name="freeMarkerConfigurer" ref="freeMarker"></property>  
  38.     </bean>  
  39. </beans>    </span>  

 模板文件目mailTemplate下的模板文件registe.ftl 【这个文件无名字、后缀无所谓,只要内容是HTML内容即可】

Html代码  收藏代码
  1. <span style="font-size: medium;"><html>    
  2.    <head>    
  3.       <meta http-equiv="content-type" content="text/html;charset=utf8">    
  4.    </head>    
  5.    <body>    
  6.        恭喜您成功注册!您的用户名为:<font color='red' size='30'>${LOGINNAME}</font>    
  7.    </body>    
  8. </html>  </span>  

 具体邮件发送类EmailService.java

  

Java代码  收藏代码
  1. <span style="font-size: medium;">package com.javacrazyer.comon;  
  2.   
  3. import java.io.File;  
  4. import java.io.UnsupportedEncodingException;  
  5. import java.util.HashMap;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8.   
  9. import javax.mail.Message;  
  10. import javax.mail.MessagingException;  
  11. import javax.mail.internet.InternetAddress;  
  12. import javax.mail.internet.MimeMessage;  
  13. import javax.mail.internet.MimeUtility;  
  14.   
  15. import org.springframework.mail.MailSender;  
  16. import org.springframework.mail.javamail.JavaMailSender;  
  17. import org.springframework.mail.javamail.MimeMessageHelper;  
  18. import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;  
  19. import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;  
  20.   
  21. import freemarker.template.Template;  
  22.   
  23. public class EmailService implements MailService {  
  24.   
  25.     private JavaMailSender mailSender;  
  26.     private FreeMarkerConfigurer freeMarkerConfigurer = null// FreeMarker的技术类  
  27.   
  28.     public void setMailSender(JavaMailSender mailSender) {  
  29.         this.mailSender = mailSender;  
  30.     }  
  31.   
  32.   
  33.   
  34.     public void setFreeMarkerConfigurer(  
  35.             FreeMarkerConfigurer freeMarkerConfigurer) {  
  36.         this.freeMarkerConfigurer = freeMarkerConfigurer;  
  37.     }  
  38.     /** 
  39.      * 发送带模板的单个html格式邮件 
  40.      */  
  41.     public void sendOrderMail(Order order) {  
  42.         MimeMessage msg = mailSender.createMimeMessage();  
  43.         // 设置utf-8或GBK编码,否则邮件会有乱码,true表示为multipart邮件  
  44.   
  45.         try {  
  46.             MimeMessageHelper helper = new MimeMessageHelper(msg, true"utf-8");  
  47.             helper.setTo(order.getUseremail()); // 邮件接收地址  
  48.             helper.setFrom("emailusername@163.com"); // 邮件发送地址,这里必须和xml里的邮件地址相同一致  
  49.             helper.setSubject("你好,恭喜你注册成功"); // 主题  
  50.             String htmlText;  
  51.             htmlText = getMailText(order.getUsername());  
  52.             helper.setText(htmlText, true); // 邮件内容,注意加参数true,表示启用html格式  
  53.         } catch (Exception e) {  
  54.             // TODO Auto-generated catch block  
  55.             e.printStackTrace();  
  56.         } // 使用模板生成html邮件内容  
  57.   
  58.         mailSender.send(msg); // 发送邮件  
  59.     }  
  60.   
  61.     /** 
  62.      * 批量发送带附件的html格式邮件,带附件 
  63.      */  
  64.     public void sendBatchEmail(Order order, List<String> address) {  
  65.           
  66.         MimeMessage msg = mailSender.createMimeMessage();  
  67.   
  68.         try {  
  69.             MimeMessageHelper helper = new MimeMessageHelper(msg, true"utf-8");  
  70.             String toList = getMailList(address);  
  71.             InternetAddress[] iaToList = new InternetAddress().parse(toList);  
  72.             msg.setRecipients(Message.RecipientType.TO, iaToList);  
  73.             helper.setFrom("emailusername@163.com");  
  74.             helper.setSubject("你好,恭喜你注册成功");  
  75.             String htmlText = getMailText(order.getUsername());  
  76.             helper.setText(htmlText, true);  
  77.             // 添加内嵌文件,第1个参数为cid标识这个文件,第2个参数为资源  
  78.             helper.addInline("a"new File("E:/11.jpg")); // 附件内容  
  79.             helper.addInline("b"new File("E:/12.jpg"));  
  80.             File file = new File("E:/各种框架图介绍.docx");  
  81.             // 这里的方法调用和插入图片是不同的,使用MimeUtility.encodeWord()来解决附件名称的中文问题  
  82.             helper.addAttachment(MimeUtility.encodeWord(file.getName()), file);  
  83.         } catch (MessagingException e) {  
  84.             // TODO Auto-generated catch block  
  85.             e.printStackTrace();  
  86.         } catch (UnsupportedEncodingException e) {  
  87.             // TODO Auto-generated catch block  
  88.             e.printStackTrace();  
  89.         } catch (Exception e) {  
  90.             // TODO Auto-generated catch block  
  91.             e.printStackTrace();  
  92.         }  
  93.   
  94.         // 如果主题出现乱码,可以使用该函数,也可以使用下面的函数  
  95.         // helper.setSubject(MimeUtility.encodeText(String text,String  
  96.         // charset,String encoding))  
  97.         // 第2个参数表示字符集,第三个为目标编码格式。  
  98.         // MimeUtility.encodeWord(String word,String charset,String encoding)  
  99.         mailSender.send(msg);  
  100.     }  
  101.   
  102.     /** 
  103.      * 集合转换字符串 
  104.      */  
  105.     public String getMailList(List<String> to) {  
  106.         StringBuffer toList = new StringBuffer();  
  107.         int length = to.size();  
  108.         if (to != null && length < 2) {  
  109.             toList.append(to.get(0));  
  110.         } else {  
  111.             for (int i = 0; i < length; i++) {  
  112.                 toList.append(to.get(i));  
  113.                 if (i != (length - 1)) {  
  114.                     toList.append(",");  
  115.                 }  
  116.             }  
  117.         }  
  118.         return toList.toString();  
  119.     }  
  120.   
  121.     // 通过模板构造邮件内容,参数content将替换模板文件中的${content}标签。  
  122.     private String getMailText(String content) throws Exception {  
  123.         String htmlText = "";  
  124.         // 通过指定模板名获取FreeMarker模板实例  
  125.         Template tpl = freeMarkerConfigurer.getConfiguration().getTemplate(  
  126.                 "registe.ftl");  
  127.         Map map = new HashMap(); // FreeMarker通过Map传递动态数据  
  128.         map.put("LOGINNAME", content); // 注意动态数据的key和模板标签中指定的属性相匹配  
  129.         // 解析模板并替换动态数据,最终content将替换模板文件中的${content}标签。  
  130.         htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(tpl, map);  
  131.         return htmlText;  
  132.     }  
  133.   
  134. }</span>  

  单一发送HTML格式的邮件测试

  

 

 

Java代码  收藏代码
  1. <span style="font-size: medium;">package com.javacrazyer.service.test;  
  2.   
  3. import org.junit.Test;  
  4. import org.springframework.context.ApplicationContext;  
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6.   
  7. import com.javacrazyer.comon.MailService;  
  8. import com.javacrazyer.comon.Order;  
  9.   
  10. public class UserServiceTest {  
  11.   
  12.     @Test  
  13.     public void test() throws InterruptedException {  
  14.         ApplicationContext context = new ClassPathXmlApplicationContext(  
  15.                 "applicationContext-html.xml");  
  16.         MailService sf = (MailService) context.getBean("emailService");  
  17.         Order order = new Order();  
  18.         order.setUsername("cheneywu");  
  19.         order.setUseremail("xxxxxx@qq.com");  
  20.         sf.sendOrderMail(order);  
  21.     }  
  22. }  
  23. </span>  

 收到邮件了


群发,带附件的测试

Java代码  收藏代码
  1. <span style="font-size: medium;">package com.javacrazyer.service.test;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import org.junit.Test;  
  7. import org.springframework.context.ApplicationContext;  
  8. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  9.   
  10. import com.javacrazyer.comon.EmailService;  
  11. import com.javacrazyer.comon.Order;  
  12.   
  13. public class UserServiceTest {  
  14.   
  15.     @Test  
  16.     public void test() throws InterruptedException {  
  17.         ApplicationContext context = new ClassPathXmlApplicationContext(  
  18.                 "applicationContext-html.xml");  
  19.         EmailService sf = (EmailService) context.getBean("emailService");  
  20.         Order order = new Order();  
  21.         order.setUsername("cheneywu");  
  22.         List<String> maillist = new ArrayList<String>();  
  23.         maillist.add("XXXXXX@qq.com");  
  24.         maillist.add("YYYYYY@qq.com");  
  25.         sf.sendBatchEmail(order, maillist);  
  26.     }  
  27. }  
  28. </span>  

 收到邮件了哦



 看到了没有,这个上边有两个接收人,下边的是附件