邮件出现乱码

来源:互联网 发布:华为如何发送网络短信 编辑:程序博客网 时间:2024/04/29 20:45
 
还在用过时的浏览器?你Out啦,请立即更换Chrome浏览器。X
“我的2011”博客频道跨年征文活动火爆上线!                                          正在写年终总结?速度参加CSDN“我的2011”征文大赛
11月热门下载资源TOP100强力推荐!                                                         点击了解英特尔云计算

spring3.0发送电子邮件(velocity模板,带附件,群发,解决乱码

分类: j2ee相关 279人阅读 评论(3)收藏 举报

在这个例子中,将与发送方相关的配置信息放在了一个email.properties文件中,spring容器启动的时候会从这个属性文件中读取发送方的配置信息,这样配置的主要原因在于,发送方一般都是固定不变的。

我将发送的内容放在一个velocity模板文件中,这个文件很像jsp文件,您可以从http://airport.iteye.com/blog/23634中获取更多的关于velocity使用方法相关的信息。(实际上velocityApache提供的一种模板语言)。我希望邮件接收方能够接收一个动态的网页,而不是一个简单的文本。

另外,程序提供了发送附件的部分,和群发的功能,只不过群发功能并不完善,因为群发过程中无法将模板变量替换成用户相关变量值,这是个缺陷,楼主也没想明白如何实现。 

下面将代码贴出,希望对大家有帮助:

先是email.properties文件:

view plaincopy to clipboardprint?
  1. email.host=smtp.163.com  
  2. email.username=woshiguanxinquan  
  3. email.password=*********  
  4. mail.smtp.auth=true  

 

模板文件:

 

view plaincopy to clipboardprint?
  1. Wecome.vm  
  2.    
  3. <html>  
  4. <body>  
  5. <h3>您好 $!{userName}, 欢迎您加入编程爱好者俱乐部!</h3>  
  6.    
  7. <div>  
  8.     您的email地址是<a href="mailto:${emailAddress}">$!{emailAddress}</a>.  
  9.   本条信息是系统自动发送,请勿回复!  
  10. </div>  
  11. </body>  
  12.    
  13. </html>  

 

简单解释一下,很明显这是个html文件,注意$!{userName}实际上是一个变量,在程序运行的时候,由model(一个hashmap类型的变量)传入的值会将其替换,(modelkey就是变量的名字,这里是userName,而value就是要替换的值),!表示如果没有替换的值,此处为空。更多详细信息请参考:http://airport.iteye.com/blog/23634

下面是spring的配置文件:

ThirdVelocityEmailConfig.xml  

view plaincopy to clipboardprint?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:security="http://www.springframework.org/schema/security"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xmlns:flex="http://www.springframework.org/schema/flex"  
  6.     xmlns:context="http://www.springframework.org/schema/context"  
  7.     xsi:schemaLocation="  
  8.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  9.        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd  
  10.        http://www.springframework.org/schema/flex  
  11.        http://www.springframework.org/schema/flex/spring-flex-1.0.xsd  
  12.        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
  13.    
  14.     <context:property-placeholder location="classpath:/com/guan/chapter19/email/email.properties"/>  
  15.     <context:annotation-config/>  
  16.     <context:component-scan base-package="com.guan.chapter19.email"/>  
  17.      
  18.      
  19.     <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">  
  20.       <property name="velocityProperties">  
  21.          <value>  
  22.           resource.loader=class  
  23.           class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader  
  24.           </value>  
  25.       </property>  
  26.    </bean>  
  27.         
  28. </beans>  

 

这个大家都熟悉,不多解释,开始的时候加载了email.properties文件,我们上面给出了,然后创建了velocityEnginebean

下面是spring的配置类:

view plaincopy to clipboardprint?
  1. package com.guan.chapter19.email;  
  2.    
  3. import java.util.Properties;  
  4.    
  5. import org.springframework.beans.factory.annotation.Value;  
  6. import org.springframework.context.annotation.Bean;  
  7. import org.springframework.context.annotation.Configuration;  
  8. import org.springframework.mail.javamail.JavaMailSender;  
  9. import org.springframework.mail.javamail.JavaMailSenderImpl;  
  10.    
  11. @Configuration  
  12. public class ThirdVelocityEmailAppConfig {  
  13.    
  14.     //从配置文件中读取相应的邮件配置属性   
  15.     private @Value("${email.host}") String emailHost;  
  16.     private @Value("${email.username}") String userName;  
  17.     private @Value("${email.password}") String password;  
  18.     private @Value("${mail.smtp.auth}") String mailAuth;  
  19.     //JavaMailSender用来发送邮件的类   
  20.     public @Bean JavaMailSender  mailSender(){  
  21.        JavaMailSenderImpl ms = new JavaMailSenderImpl();  
  22.        ms.setHost(emailHost);  
  23.        ms.setUsername(userName);  
  24.        ms.setPassword(password);  
  25.        Properties pp = new Properties();  
  26.        pp.setProperty("mail.smtp.auth", mailAuth);  
  27.        ms.setJavaMailProperties(pp);  
  28.        return ms;     
  29.     }    
  30. }  

 

对于spring是否应该由类来配置,我并不关心,一般情况下,我更倾向于annotation这种形式,因为看起来比xml舒服点,但是annotation不能完全取代xml配置方式(至少现在是这样的),当然您完全可以使用xml进行bean的配置,效果是一样的。在这个配置类中,将从email.properties中读取的值赋值给了JavaMailSenderImpl,这个对象是java邮件发送的主要类,使用其send方法可以将预先准备好的消息发送出去。 

下面给出发送服务的源码

view plaincopy to clipboardprint?
  1. package com.guan.chapter19.email;  
  2.    
  3. import java.io.File;  
  4. import java.util.Map;  
  5.    
  6. import javax.mail.internet.MimeMessage;  
  7.    
  8. import org.apache.velocity.app.VelocityEngine;  
  9. import org.springframework.beans.factory.annotation.Autowired;  
  10. import org.springframework.core.io.FileSystemResource;  
  11. import org.springframework.mail.javamail.JavaMailSender;  
  12. import org.springframework.mail.javamail.MimeMessageHelper;  
  13. import org.springframework.mail.javamail.MimeMessagePreparator;  
  14. import org.springframework.stereotype.Component;  
  15. import org.springframework.ui.velocity.VelocityEngineUtils;  
  16.    
  17. @Component  
  18. public class ThirdVelocityEmailService {  
  19.    
  20.     private JavaMailSender  mailSender;  
  21.     private VelocityEngine velocityEngine;  
  22.      
  23.     @Autowired  
  24.     public void setMailSender(JavaMailSender  mailSender)  
  25.     {  
  26.        this.mailSender = mailSender;  
  27.     }  
  28.      
  29.     @Autowired  
  30.      
  31.     public void setVelocityEngine(VelocityEngine velocityEngine)  
  32.     {  
  33.        this.velocityEngine = velocityEngine;  
  34.     }  
  35.      
  36.     public void sendEmail(final Map<String,Object> model,final String subject,final String vmfile,final String[] mailTo,final String [] files)  
  37.     {    
  38.        MimeMessagePreparator preparator = new MimeMessagePreparator() {  
  39.            //注意MimeMessagePreparator接口只有这一个回调函数  
  40.          public void prepare(MimeMessage mimeMessage) throws Exception  
  41.          {  
  42.             MimeMessageHelper message = new MimeMessageHelper(mimeMessage,true,"GBK");  
  43.             //这是一个生成Mime邮件简单工具,如果不使用GBK这个,中文会出现乱码  
  44.             //如果您使用的都是英文,那么可以使用MimeMessageHelper message = new MimeMessageHelper(mimeMessage);  
  45.             message.setTo(mailTo);//设置接收方的email地址  
  46.             message.setSubject(subject);//设置邮件主题  
  47.             message.setFrom("woshiguanxinquan@163.com");//设置发送方地址  
  48.              String text = VelocityEngineUtils.mergeTemplateIntoString(  
  49.                velocityEngine, vmfile,"GBK", model);  
  50.              //从模板中加载要发送的内容,vmfile就是模板文件的名字  
  51.              //注意模板中有中文要加GBK,model中存放的是要替换模板中字段的值  
  52.             message.setText(text, true);  
  53.             //将发送的内容赋值给MimeMessageHelper,后面的true表示内容解析成html  
  54.             //如果您不想解析文本内容,可以使用false或者不添加这项  
  55.             FileSystemResource file;  
  56.             for(String s:files)//添加附件  
  57.             {  
  58.                file = new FileSystemResource(new File(s));//读取附件  
  59.                message.addAttachment(s, file);//向email中添加附件  
  60.             }  
  61.           }  
  62.       };  
  63.    
  64.        mailSender.send(preparator);//发送邮件   
  65.     }  
  66.      
  67. }  

 

主要是mailSend这个方法,在这个方法里先创建了一个消息,然后调用mailSender将消息发送出去。 

最后给出测试程序:

view plaincopy to clipboardprint?
  1. package com.guan.chapter19.email;  
  2.    
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.    
  6. import org.junit.Test;  
  7. import org.springframework.context.ApplicationContext;  
  8. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  9.    
  10. public class ThirdVelocityEmailTest {  
  11.    
  12.     @Test  
  13.     public void sendEmail()  
  14.     {  
  15.        ApplicationContext context =  
  16.            new ClassPathXmlApplicationContext("com/guan/chapter19/email/ThirdVelocityEmailConfig.xml");  
  17.        ThirdVelocityEmailService tves = context.getBean(ThirdVelocityEmailService.class);  
  18.        Map<String,Object> model = new HashMap<String,Object>();  
  19.        model.put("userName","大关");  
  20.        model.put("emailAddress""woshidaguan@126.com");  
  21.        tves.sendEmail(model,"欢迎您的加入","com/guan/chapter19/email/welcome.vm",new String[]{"woshiguanxinquan@163.com"},new String[]{"F:/Sunset.jpg","F:/spring-hibernate.rar"});  
  22.        //参数说明:替换velocity模板的变量和值对,邮件主题,velocity模板文件的路径,接收方email地址,附件  
  23.        //简单说明,如果您要群发,可以在接收方email地址中多传入几个email地址,附件可以一次发送多个  
  24.     }  
  25. }  

 

 

这个程序对一个email来说功能已经很全面了,您可以对其更改然后应用于您的程序中。

 

再次简单说明一下,主机的信息配置在mail.properties文件中,发送的内容写在velocity模板文件中,在执行的时候将相应的字段进行替换。使用了MimeMessagePreparator进行复杂邮件的发送,MimeMessageHelper帮助简化邮件信息过程。解决了中文乱码问题。

完毕!


有问题欢迎加入群号探讨:173711587

 

查看评论
2楼 jsyzthz2011-08-07 21:04发表 [回复] [引用][举报]
从126的发到QQ的附件打不开。
从126的发送到GMAIL可以打开。
1楼 jsyzthz2011-08-07 20:56发表 [回复] [引用][举报]
小弟我测试了一下,发现个问题,我添加附件的时候发送到我QQ邮箱然后随便怎么死活也打不开。不知道楼主是否测试过附件。还有有中文我建议国际化用UTF-8。你说有中文只能用GBK,我估计楼主的项目默认编码是GBK的,一旦用UTF-8就会乱码,你可以试试吧eclipse的默认编码改成UTF-8或者把单个项目改改试试。至少我是用UTF-8测试成功了,还请楼主多多指教!!
Re: shimiso2011-08-11 17:28发表 [回复] [引用][举报]
回复jsyzthz:恩,说的有理,个别邮箱附件是会遇到问题,那你可以用MimeMultipart类来包一下附件,set到MimeMessage的内容里面,通常这么干是比较正规的,具体程序参考如下,详细可以查阅资料
view plaincopy to clipboardprint?
  1. Multipart mp = new MimeMultipart();  
  2. //向Multipart添加正文   
  3. MimeBodyPart content = new MimeBodyPart();  
  4. content.setText(text);  
  5. //向MimeMessage添加(Multipart代表正文)  
  6. mp.addBodyPart(content);  
  7. sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();  
  8. files.add("src/main/log4j.properties");  
  9. //向Multipart添加附件   
  10. Iterator it = files.iterator();  
  11. while (it.hasNext()) {  
  12. MimeBodyPart attachFile = new MimeBodyPart();  
  13. String filename = it.next().toString();  
  14. FileDataSource fds = new FileDataSource(filename);  
  15. attachFile.setDataHandler(new DataHandler(fds));  
  16. attachFile.setFileName("=?GBK?B?"  
  17. + enc.encode(fds.getName().getBytes()) + "?=");  
  18. mp.addBodyPart(attachFile);}  
  19. files.clear();  
  20. //向Multipart添加MimeMessage   
  21. mimeMessage.setContent(mp);  
Multipart mp = new MimeMultipart(); //向Multipart添加正文 MimeBodyPart content = new MimeBodyPart(); content.setText(text); //向MimeMessage添加(Multipart代表正文) mp.addBodyPart(content); sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder(); files.add("src/main/log4j.properties"); //向Multipart添加附件 Iterator it = files.iterator(); while (it.hasNext()) { MimeBodyPart attachFile = new MimeBodyPart(); String filename = it.next().toString(); FileDataSource fds = new FileDataSource(filename); attachFile.setDataHandler(new DataHandler(fds)); attachFile.setFileName("=?GBK?B?" + enc.encode(fds.getName().getBytes()) + "?="); mp.addBodyPart(attachFile);} files.clear(); //向Multipart添加MimeMessage mimeMessage.setContent(mp);
 
发表评论
  • 用 户 名:
  • hahajingshiwo
  • 评论内容:
  • 插入代码
    HTML/XMLJavaScriptCSSPHPC#C++JavaPythonRubyVisual BasicDelphiSQL其它
      
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料

    shimiso
    • 访问:40503次
    • 积分:1920分
    • 排名:第2235名
    • 原创:135篇
    • 转载:14篇
    • 译文:8篇
    • 评论:85条
    文章分类
  • Linux(3)
  • Android开发(26)
  • IDE工具(4)
  • j2ee相关(53)
  • java基础(16)
  • 数据库(10)
  • ruby(2)
  • Flex(0)
  • webservice(2)
  • WEB相关(14)
  • 云计算(2)
  • 其他(5)
  • 服务器(15)
    文章存档
  • 2011年12月(3)
  • 2011年11月(6)
  • 2011年10月(2)
  • 2011年09月(7)
  • 2011年08月(12)
  • 2011年07月(8)
  • 2011年06月(1)
  • 2011年05月(5)
  • 2011年04月(2)
  • 2011年03月(4)
  • 2011年02月(1)
  • 2011年01月(5)
  • 2010年12月(3)
  • 2010年11月(5)
  • 2010年10月(2)
  • 2010年09月(6)
  • 2010年08月(1)
  • 2010年07月(6)
  • 2010年06月(9)
  • 2010年05月(7)
  • 2010年04月(17)
  • 2010年03月(10)
  • 2010年01月(4)
  • 2009年12月(2)
  • 2009年11月(3)
  • 2009年10月(26)
    展开
    阅读排行
  • 关于做android系统集成开发的一点心... (6778)
  • Android(三)数据存储之XML解析... (1616)
  • Android(五)数据存储之五网络多线... (1287)
  • Tomcat 6.0 开发配置小结 (1145)
  • Android(三) 数据存储之二 Sh... (994)
  • request.getInputStre... (974)
  • 程序调用飞信API发送免费短信(JAVA... (930)
  • Android(五)数据存储之五网络数据... (851)
  • wml表单提交 (810)
  • spring的BeanUtils.cop... (797)
    评论排行
  • 关于做android系统集成开发的一点心... (57)
  • wml表单提交 (3)
  • spring3.0发送电子邮件(velo... (3)
  • android 多线程断点续传下载 二 (2)
  • java 反射机制 (2)
  • android 多任务多线程下载 一 (2)
  • Android开发(一)发送短信程序 (2)
  • Android(三)数据存储之XML解析... (1)
  • 程序调用飞信API发送免费短信(JAVA... (1)
  • spring的BeanUtils.cop... (1)
    推荐文章
      最新评论
    • Myeclipse10下载,安装,破解,插件,优化介绍(CSDN首发)

      Augus_an: 保存啦

    • 自定义ListView【通用】适配器并实现监听控件!

      liuhao1201: 请将这篇文章标成转载,并注明来源。谢谢~

    • oracle经典sql练习题

      c5153000: 你的第六题是不是可以写成这样呢? select * from emp where deptno=10...

    • android 多线程断点续传下载 二

      ge_zhiqiang: 顶起,期待中....

    • android 多线程断点续传下载 二

      asparation: 期待下一集

    • android 多任务多线程下载 一

      coding_or_coded: 说实话,写的真不错,建议添加暂停下载功能。这个还是比较重要的。

    • android 多任务多线程下载 一

      asparation: 呵呵,写的好啊,期待下一篇ing

    • Java容易搞错的知识点

      ureygo: 总结的好!有收获,最后的对象引用2.append方法中第一次b=a,-->b。因为a,b都为main...

    • Spring2.5 JMS整和ActiveMQ 5.5

      lxy66: 你的jar包能给我么

    • 关于做android系统集成开发的一点心得

      fa12354654: 写得真好。

    公司简介|招贤纳士|广告服务|银行汇款帐号|联系方式|版权声明|法律顾问|问题报告
    北京创新乐知信息技术有限公司 版权所有, 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    江苏乐知网络技术有限公司 提供商务支持
    Email:webmaster@csdn.net
    Copyright © 1999-2011, CSDN.NET, All Rights Reserved
    GongshangLogo
    英特尔全国技术博客大奖赛精选close
    • 1、OpenCV轻松进阶初级篇-安装OpenCV
    • 2、OpenCV轻松进阶初级篇-编译OpenCV
    • 3、教你轻轻松松打包Web应用
    • 4、Android已经开始领跑?
    • 5、行业分析文章总汇
    • 6、Intel Media SDK常见问题之解答
    • 7、QT和MeeGo文章总汇
    • 8、一篇云计算的成功案例
    原创粉丝点击