随笔-126  评论-247  文章-5  trackbacks-0

前言:谈过如何用 Spring 发送普通 Email 和带有附件的 Email 之后,接着来谈一下如何用 Spring 来发送 Html 式的 Email。
发送 Html 格式的 Email 也是很必要的,现在的很多网站在用户注册之后都会发一封 Email 到用户的邮箱,用户需要点击
邮件中的链接来完成注册,这个链接如果是用普通文本式的 Email 来发送的话,这个链接是不能被点击的,因为它是文本内容,
所以有必要要学一下 怎么样发送 Html 式的 Email。但这个初次尝试起来有点纠结,先来看问题,然后再贴代码:
在测试的时候,遇到两个问题,问题一: 中文乱码 ,问题二:资源无法显示;下面是收到的邮件截图:




问题一可以在 Spring 的 API 中找到答案,就是要花点时间来调试

说到问题二,这个有点让人头疼,因为官方文档是这么说的(Spring 2.5.6):


我测试的时候也是按着官方文档的示例来实验的,但事实证明,这是不行的,收到的邮件,这个图片资源总是显示不出来,
右键查看一下没有显示出来的资源属性:


这个问题在官方文档上没有做出相关的解释,于是自己试着去实验,原来是 jar 包版本的问题,当然,这不可能是一下子就
能想得到是 jar 包出的问题,也没有一个人会轻易的去怀疑官方的东西吧,不过这个算是 Spring 2.5.6 的 Bug 吧。
我把 Spring 2.5.6 的 spring-context-support 的 jar 包换成 Spring 3.1.0 的 spring-context-support jar 包之后来实验,OK,问题解决。
顺便说一下 Spring 的 spring-context-support 这个 jar 包,就像你看到的,support,就是 Spring 支持的一些扩展服务(如果没有解释错误的话-_-|)
这个 jar 包封装了一些 Email 和 Scheduling(Spring 定时服务,计划任务),还有 Freemarker、Velocity,下次会说一下 Spring 定时服务。
好了,就到这吧,接下来贴代码:

环境:
Spring     2.5.6
Spring-context-support 3.1.0
Javamail  1.4.4
Maven     3.0.4
Myeclipse 8.6.1

项目结构:


spring-smtp-mail-inline.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  
    
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
       
<!-- 服务器 -->
        
<property name="host" value="smtp.yeah.net" />
        
<!-- 端口号 -->
        
<property name="port" value="25" />
        
<!-- 用户名 -->
        
<property name="username" value=fancydeepin@yeah.net />
        
<!--  密码   -->
        
<property name="password" value="***********"/>
        
<!-- SMTP服务器验证 -->
        
<property name="javaMailProperties">
            
<props>
               
<!-- 验证身份 -->
              
<prop key="mail.smtp.auth">true</prop>
          
</props>
        
</property>
    
</bean>
    
<!-- 
       目前我用过的EMAIL账号都是网易的,下面列出网易的SMTP服务器名和端口号:
       网易邮箱         SMTP服务器     SMTP端口    POP3服务器     POP3端口
       @126.com    smtp.126.com      25         pop3.126.com     110
       @163.com    smtp.163.com      25         pop3.163.com     110
       @yeah.net   smtp.yeah.net      25         pop3.yeah.net    110
    
-->
    
    
<bean id="simpleMailMessage" class="org.springframework.mail.SimpleMailMessage">
      
<!-- 发件人email -->
        
<property name="from" value="fancydeepin@yeah.net" />
        
<!-- 
         收件人email
        <property name="to" value="to@yeah.net" />
        email主题(标题)
        <property name="subject" value="Subject" />
        email主题内容
        <property name="text">
          <value>ContentText</value>
        </property>
        
-->
    
</bean>
    
    
<bean id="simpleMail" class="com.fancy.util.Email">
        
<property name="javaMailSender" ref="javaMailSender" />
        
<property name="simpleMailMessage" ref="simpleMailMessage" />
    
</bean>
    
</beans>

Email.java
package com.fancy.util;

import javax.mail.internet.MimeMessage;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
/**
 * -----------------------------------------
 * @文件: Email.java
 * @作者: fancy
 * @邮箱: fancydeepin@yeah.net
 * @时间: 2012-6-12
 * @描述: 发送Email工具类
 * -----------------------------------------
 
*/

public class Email {
    
    
private JavaMailSender javaMailSender;
    
private SimpleMailMessage simpleMailMessage;
    
  
/**
     * @方法名: sendMail 
     * @参数名:
@param subject  邮件主题
     * @参数名:
@param content 邮件主题内容
     * @参数名:
@param to         收件人Email地址
     * @描述语: 发送邮件
     
*/

    
public void sendMail(String subject, String content, String to) {
        
        
try {
            MimeMessage mimeMessage 
= javaMailSender.createMimeMessage();
          
/**
             * new MimeMessageHelper(mimeMessage,true)之true个人见解:
             * 关于true参数,官方文档是这样解释的:
             * use the true flag to indicate you need a multipart message
             * 翻译过来就是:使用true,以表明你需要多个消息
             * 再去翻一下MimeMessageHelper的API,找到这样一句话:
             * supporting alternative texts, inline elements and attachments
             * 也就是说,如果要支持内联元素(HTML)和附件就必须给定第二个参数为true
             * 否则抛出 java.lang.IllegalStateException 异常
             
*/

          
/**
             * 刚开始收到邮件显示中文乱码,于是赶紧查看官方文档,没有提到,再查阅API,也没有查到Set编码的方法,
             * 于是就在HTML里面自己指定编码,也不起作用,邮件还是显示中文乱码;
             * 最后的结论是:如果HTML内容含有中文必须指定HTML的编码,默认是ISO-8859-1,所以会显示中文乱码
             * 在MimeMessageHelper的构造方法中找到:
             * MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, String encoding)
             * 实验一下,OK,原来编码是在这儿设置,没事了,中文正常显示
             
*/

            MimeMessageHelper messageHelper 
= new MimeMessageHelper(mimeMessage,true,"UTF-8");
            messageHelper.setFrom(simpleMailMessage.getFrom()); 
//设置发件人Email
            messageHelper.setSubject(subject); //设置邮件主题
            messageHelper.setText(content);   //设置邮件主题内容
            messageHelper.setTo(to);          //设定收件人Email
            
//步骤 1
            //资源的引用方法:cid:你自己设置的资源ID

            messageHelper.setText( 
            
"<html>" + 
              
"<body>" +
                
"<BR>" +
                
"<div align='center'>" +
                  
"<img src='cid:imageid'/>" +
                  
"<BR>" +
                  
"<h4>" +
                    
"返回 fancydeepin 的Blogjava:" +
                    
"<a href='http://www.blogjava.net/fancydeepin/'>http://www.blogjava.net/fancydeepin/</a>" +
                  
"</h4>" +
                
"</div>" +
              
"</body>" +
            
"</html>"true);
          
/**
             * ClassPathResource:很明显就是类路径资源,我这里的附件是在项目里的,所以需要用ClassPathResource
             * 如果是系统文件资源就不能用ClassPathResource,而要用FileSystemResource,例:
             * FileSystemResource file = new FileSystemResource(new File("D:/woniu.png"));
             
*/

          
/**
             * 如果想在HTML中使用资源,必须在HTML中通过资源 ID 先引用资源,然后才来加载资源
             
*/

            
//步骤 2
            ClassPathResource image = new ClassPathResource("images/body.png");
            messageHelper.addInline(
"imageid", image);
            javaMailSender.send(mimeMessage);    
//发送HTML邮件
            
        }
 catch (Exception e) {System.out.println("异常信息:" + e);}
    }

    
//Spring 依赖注入
    public void setSimpleMailMessage(SimpleMailMessage simpleMailMessage) {
        
this.simpleMailMessage = simpleMailMessage;
    }

    
//Spring 依赖注入
    public void setJavaMailSender(JavaMailSender javaMailSender) {
        
this.javaMailSender = javaMailSender;
    }

}


接下来的是测试类,这里的测试类我又用了两个,一个是 Main 方法测试,另外一个 Junit 测试,个人不太喜欢 Junit 的测试,下面贴 Main 方法的测试
Test.java
package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.fancy.util.Email;
/**
 * -----------------------------------------
 * @文件: Test.java
 * @作者: fancy
 * @邮箱: fancydeepin@yeah.net
 * @时间: 2012-6-12
 * @描述: 测试HTML邮箱发送类
 * -----------------------------------------
 
*/

public class Test {

    
public static void main(String[] args) {
        ApplicationContext context 
= new ClassPathXmlApplicationContext("spring-smtp-mail-inline.xml");
        Email mail 
= (Email)context.getBean("simpleMail");
        mail.sendMail(
"Spring SMTP Mail HTML Subject""Spring SMTP HTML Text Content""fancyzero@yeah.net");
        
//mail.sendMail("标题", "内容", "收件人邮箱");
    }

}


pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation
="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  
<modelVersion>4.0.0</modelVersion>
  
<groupId>com.fancy</groupId>
  
<artifactId>spring-mail-inline-example</artifactId>
  
<version>1.0</version>
  
<packaging>jar</packaging>
  
<name>spring-mail-inline-example</name>
  
<url>http://maven.apache.org</url>
  
<properties>
    
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  
</properties>

  
<dependencies>
    
<!-- Spring framework -->
    
<dependency>
      
<groupId>org.springframework</groupId>
      
<artifactId>spring</artifactId>
      
<version>2.5.6</version>
    
</dependency>
    
<!-- Spring Support -->
    
<dependency>
      
<groupId>org.springframework</groupId>
      
<artifactId>spring-context-support</artifactId>
      
<version>3.1.0.RELEASE</version>
    
</dependency>
    
<!-- Javamail API -->
    
<dependency>
      
<groupId>javax.mail</groupId>
      
<artifactId>mail</artifactId>
      
<version>1.4.4</version>
    
</dependency>
    
<!-- Junit -->
    
<dependency>
      
<groupId>junit</groupId>
      
<artifactId>junit</artifactId>
      
<version>3.8.1</version>
      
<scope>test</scope>
    
</dependency>
  
</dependencies>
  
</project>

Run Test.java,收到并打开邮件:


OK,没问题了这回。最后提一下在 Email.java 中为什么步骤1和步骤2不能倒过来的原因,其实你看到这里也可以自己试一下,你会
发现倒过来真的不行的,原因嘛,这个官方文档有提到一点,这个我就不贴了,我贴一下 API 中对这个的解释,在 API 中还给出了
如何通过资源 ID 来引用资源的,英文的,自己看哦:





  
posted on 2012-06-12 13:05 fancydeepin 阅读(4218) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: