基于Spring+freemark+javax.mail邮件发送工具

前段时间,有兴趣去研究了一下基于java的邮件发送功能,还颇有趣味,在此做出一个分享。

java提供了一个jar包,javax.mail专门用来做邮件功能,当然Spring也集成了org.springframework.mail包和子包org.springframework.mail.javamail来提供邮件的封装。我这里使用的是SpringMVC环境,所以集成spring工具包来说方便一些。

freemark主要是用来制作邮件模板,因为发送的邮件可能需要一些样式布局什么的,所有模板就显得尤为重要了。

参考博客:

本文将分为两个部分来讲解:
1.利用freemark集成邮件模板。
2.通过org.springframework.mail包发送模板邮件。

一:利用freemark集成邮件模板

通过java程序发送邮件,可以发送纯文本文件,但是不够美观,所有利用freemark制作一个html模板,就显得很有必要了。先来看我们最终的效果。

 使用模板除了在于界面的美化,也在于他的通用性。像上面的这个模板,其中的一些必定是可变的,例如“会议名称”“会议时间”“会议地点”“会议积分”“会议描述”“其他”等等。

1.引入依赖包
因为是在SpringMVC的基础上集成的功能所以spring的基本jar包是必要的,这里就不列举了,只列举出freemark相关包。

pom.xml:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.7.RELEASE</version>
</dependency>
<dependency>
   <groupId>freemarker</groupId>
   <artifactId>freemarker</artifactId>
   <version>2.3.9</version>
   <type>pom</type>
</dependency>

2.spring-mvc.xml中配置FreeMarkerConfigure的bean
spring-mvc.xml是spring的配置文件,可能你的配置叫applicationContext.xml 不重要,重要的是你知道他是一个bean就行了,配到<beans></beans>里面。
关于freemark的其他相关配置,在这里不做过多分析,当使用到的时候,再去参考freemark文档吧。

spring-mvc.xml:
<!-- Freemarker配置 -->
     <bean id="freemarkerConfig"  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
         <property name="templateLoaderPath" value="/WEB-INF/freemarker/" />               <!--配置模板文件存放路径-->
         <property name="freemarkerSettings">
             <props>
                 <prop key="locale">zh_CN</prop>                                            <!--其他相关配置,请参考freemark教程-->
                 <prop key="template_update_delay">1800</prop>
                 <prop key="default_encoding">UTF-8</prop>
                 <prop key="number_format">0.##########</prop>
                 <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                 <prop key="classic_compatible">true</prop>
                 <prop key="template_exception_handler">ignore</prop>
             </props>
         </property>
     </bean>

3.制作freemark模板
freemark利用嵌入html的标签来动态的生成页面,关于freemark的语法,这里给出一个参考博客点击打开链接

classNotice.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
     <head>
           <meta http-equiv="content-type" content="text/html;charset=utf8">
           <title>邮件模板</title>
     </head>
     <body>
           <style type="text/css">
                table,table tr th, table tr td { border:1px solid #ccc; }
                table { width: 600px; min-height: 25px; line-height: 25px; border-collapse: collapse; margin:10px 20px}
                .td1{
                     text-align:center;width:100px;
                }
                .gogo{
                     width:86px;height:30px;background-color:#009688;font-size:10px;text-align:center;line-height:30px;cursor:pointer;margin-bottom:10px
                }
                .gogo a{
                     color:#ffffff;
                }
           </style>
           <div style="width:80%;height:530px;margin:0 auto;border:1px solid #ccc;border-bottom:none;">
                <div style="width:100%;height:58px;background-color:#393D49;line-height:58px">
                     <div style="width:45px;height:45px;background:url('cid:note') center no-repeat;margin:7px 0 0 10px;float:left"></div>
                     <a style="color:#009688;margin-left:10px;font-family:黑体;font-size:25px;float:left">XX后台管理系统</a>
                </div>
                <div style="height:222px;padding:10px 20px;color:#393D49">
                     <i>Hi,亲爱的XX同事:</i>
                     <div style="margin:20px 0">您好,特此通知您参加XX会议</div>
                     <table>
                           <tr>
                                <td class="td1">【会议名称】</td>
                                <td>${className}</td>
                           </tr>
                           <tr>
                                <td class="td1">【会议时间】</td>
                                <td>${classDate}</td>
                           </tr>
                           <tr>
                                <td class="td1">【会议地点】</td>
                                <td>${classAddr}</td>
                           </tr>
                           <tr>
                                <td class="td1">【会议积分】</td>
                                <td>${classScore}分</td>
                           </tr>
                           <tr>
                                <td class="td1">【会议描述】</td>
                                <td>${classDesc}</td>
                           </tr>
                           <#if (other!='')>
                           <tr>
                                <td class="td1">【其他】</td>
                                <td>${other}</td>
                           </tr>
                           </#if>
                     </table>

                     <div class="gogo"><a href="${url}">了解详情</a></div>
                     <ul>
                           <li>
                                <i>会议成绩和积分将影响员工绩效等,请务必准时参加。</i>
                           </li>
                           <li>
                                <i>更多会议信息,请登录<a href="${url}" style="color:#009688">XX后台管理系统</a>,或直接访问:<span style="color:#009688">${url}</span></i>
                           </li>
                           <li>
                                <i>如有疑问,请咨询管理员<span style="color:#FF5722">@${author}</span></i>
                           </li>
                           <li>
                                <i>本邮件由XX后台管理系统发出,请勿直接回复!祝您工作愉快,谢谢!</i>
                           </li>
                     </ul>

                </div>
           </div>
           <div style="width:80%;height:30px;line-height:30px;color:#ccc;font-size:12px;margin:0 auto;text-align:center;border:1px solid #ccc;border-top:none;background-color:#FBFBFB">
                <span>©XXXXXX有限公司</span>
           </div>
     </body>
</html>
模板中利用${ }来动态的插入参数,利用<#if (other!=' ')></if>来做条件判断。模板中嵌入图片background:url('cid:note')
 
4.加载模板文件
一切准备就绪,现在就是需要在java中加载模板,并生成最后的String类型text。创建一个邮件发送工具类EmailUtil。

EmailUtil.java:
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.mail.MailAuthenticationException;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.sun.mail.util.MailConnectException;

import freemarker.template.Template;

/**
 * 
 * @ClassName: EmailUtil
 * @Description: 邮件操作工具类
 * @author aggerChen
 * @date 2017年7月31日 上午10:16:15
 * @version 0.0.1
 */
public class EmailUtil{


    /**
     * 
     * @MethodName: getMailText
     * @Description: 获取邮件文本(通过加载FreeMarker模板HTML)
     * @param freemarkerConfig 配置文件
     * @param freemarkerFileName 模板名 eg: "classNotice.html"
     * @param map 模板动态数据值
     * @return
     * @throws Exception String
     */
    public static String getMailText(FreeMarkerConfigurer freemarkerConfig,
            String freemarkerFileName,Map<String,String> map) throws Exception {  
        // 通过指定模板名获取FreeMarker模板实例  
        Template template = freemarkerConfig.getConfiguration().getTemplate(freemarkerFileName);   
        // 解析模板并替换动态数据,最终content将替换模板文件中的${content}标签。  
        String htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);  
        return htmlText;  
    } 
}

这个工具类我们后面还会添加其他方法。
现在只创建了一个方法,返回最终的html字符串,getMailText 需要参数
FreeMarkerConfigurer  freemarkerConfig:是在Spring配置文件中配置的bean,需要我们在controller中注入。
String freemarkFileName:模板文件名,就是传入我们上面的模板文件“classNotice.html”
Map<String,String> map :模板中变量键值对。

5.创建controller,调用工具类
创建一个controller,用来执行发送邮件命令。先获取到模板字符串。

ClassController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

/**
 *
 * @ClassName: ClassesController
 * @Description: 课程管理
 * @author aggerChen
 * @date 2017年4月10日 上午10:01:34
 */
@Controller
@RequestMapping("classes")
public class ClassesController{

     @Autowired
     private FreeMarkerConfigurer freemarkerConfig;                  //依赖注入spring-mvc.中配置的bean 邮件模板配置

     /**
      *
      * @MethodName: sendEmail
      * @Description: 发送邮件通知
      */
     @RequestMapping("/sendEmail")
     @ResponseBody
     public Result sendEmail(Long classId,String addr,String other,HttpServletRequest request,HttpSession session){
           Result result = new Result(-1, "通知邮件发送失败!");
     
           //用Map存储变量名和变量值映射,用于注入模板中${}引用的变量
           Map<String, String> map = new HashMap<>();
           map.put("className", "关于拉格朗日中值定理与牛顿-莱布尼茨公式在日常代码中的应用会议");                //会议名
           map.put("classDate", "2017-08-30 15:23:00");                                                 //会议时间
           map.put("classAddr", "会议室");                       //会议地点
           map.put("classScore", 5);                            //会议积分
           map.put("author", "管理员");                          //邮件作者
           map.put("classDesc", "描述描述描述");                  //描述
           map.put("other", "无");                              //其他
           map.put("url", "http://www.xxx.com");                //项目访问地址

          //调用工具类,传入参数生成模板String
          String text = EmailUtil.getMailText(freemarkerConfig, "classNotice.html", map);
         //生成text备用,以便后续传递给邮件发送。还有,模板中有一个图片,也需要我们注入,后面慢慢讲来
          ...
     }

}
其中调用了工具类EmailUtil.getMailText方法,传入了注入的freemarkerConfig,模板名和模板变量键值映射
至此第一部分,获取模板字符串就完成了,其中模板中嵌入图片,要在后面讲解。第二部分则,利用获取到的text发送邮件。如下


二:通过org.springframework.mail包发送模板邮件

要试用spring封装包发送邮件,则需要引入一下相关jar包

pom.xml:
<dependency>
        <groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
	<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
       <groupId>com.sun.mail</groupId>
       <artifactId>javax.mail</artifactId>
       <version>1.5.5</version>
</dependency>


1.创建一个config,properties文件
用来配置发送邮件的基本信息。

config.properties:
#邮件发送配置
emailHost:smtp.exmail.qq.com
emailPort:587
emailFrom:[email protected]
emailPwd:xxxxx
其中配置了固定的邮件发送host,port 不同的邮箱host和port是不同的,我这里用的是腾讯企业邮箱,其他的邮箱发送配置可以自行查询一下。
配置发送者邮箱地址和密码。我这里发送者是固定的,所以在这里配置,如果不固定,则到时候发送的时候在传过去就行了。

2.创建一个邮件配置类
用于存放邮件发送的一些配置信息。

EmailConfig.java:
/**
     *
     * @ClassName: EmailConfig
     * @Description: 邮件配置类
     * @author aggerChen
     * @date 2017年8月2日 下午3:13:21
     */
    public static class EmailConfig{
     private String host;            //发送邮件的host
     private int port;               //发送端口
     private String from;            //邮件发送者
     private String fromPwd;         //邮件发送者密码
     private String[] toArr;         //邮件接收者数组
     private String[] CcArr;         //邮件抄送数组
     private String subject;         //邮件主题
     private String text;            //邮件文本
     private Map<String,File> inLineMap;        //嵌入到模板中的图片

     //无参构造
     public EmailConfig() {
           super();
           this.inLineMap = new HashMap<>();
     }
     //重载构造
     public EmailConfig(String host, int port, String from, String fromPwd,String[] toArr,String[] CcArr, String subject, String text) {
           this();
           this.host = host;
           this.port = port;
           this.from = from;
           this.fromPwd = fromPwd;
           this.toArr = toArr;
           this.CcArr = CcArr;
           this.subject = subject;
           this.text = text;

     }
     /**
      * 重载构造
      * @Description: 通过依赖配置文件获取host和port
      * @param from
      * @param fromPwd
      * @param to
      * @param toArr
      * @param CcArr
      * @param subject
      * @param text
      */
     public EmailConfig(String from, String fromPwd,String[] toArr,String[] CcArr, String subject, String text) {
          this(null,-1,from,fromPwd,toArr,CcArr,subject,text);
          try {
              this.host = SystemConfig.getResource("emailHost");                         //调用了另外一个工具类SystemConfig来获取我们在config.properties中配置的信息。
              this.port = Integer.parseInt(SystemConfig.getResource("emailPort"));
          } catch (IOException e) {
              e.printStackTrace();
          }
     }
     /**
      * 重载构造
      * @Description: 通过依赖配置文件获取host和port,from,pwd
      * @param toArr   邮件接收者数组 eg: {"[email protected]","[email protected]"}
      * @param CcArr   邮件抄送者数组 eg: {"[email protected]","[email protected]"}
      * @param subject 邮件主题
      * @param text    邮件正文
      */
     public EmailConfig(String[] toArr,String[] CcArr, String subject, String text) {
          this(null,-1,null,null,toArr,CcArr,subject,text);
          try {
               this.host = SystemConfig.getResource("emailHost");
               this.port = Integer.parseInt(SystemConfig.getResource("emailPort"));
               this.from = SystemConfig.getResource("emailFrom");
               this.fromPwd = SystemConfig.getResource("emailPwd");
          } catch (IOException e) {
               e.printStackTrace();
          }
     }
     /**
      * 重载构造
      * @Description: 通过依赖配置文件获取host和port,from,pwd
      * @param toArr   邮件接收者数组 eg: {"[email protected]","[email protected]"}
      * @param subject 邮件主题
      * @param text    邮件正文
      */
      public EmailConfig(String[] toArr, String subject, String text) {
          this(null,-1,null,null,toArr,null,subject,text);
          try {
              this.host = SystemConfig.getResource("emailHost");
              this.port = Integer.parseInt(SystemConfig.getResource("emailPort"));
              this.from = SystemConfig.getResource("emailFrom");
              this.fromPwd = SystemConfig.getResource("emailPwd");
          } catch (IOException e) {
              e.printStackTrace();
          }
      }


      /**
       *
       * @MethodName: putInLineVal
       * @Description: 向配置中追加模板参数
       * @param key
       * @param file void
       */
       public void putInLineVal(String key,File file){
           this.inLineMap.put(key, file);
       }


     public String getFrom() {
           return from;
     }
     public void setFrom(String from) {
           this.from = from;
     }
     public String getFromPwd() {
           return fromPwd;
     }
     public void setFromPwd(String fromPwd) {
           this.fromPwd = fromPwd;
     }
     public String[] getToArr() {
           return toArr;
     }
     public void setToArr(String[] toArr) {
           this.toArr = toArr;
     }
     public String getSubject() {
           return subject;
     }
     public void setSubject(String subject) {
           this.subject = subject;
     }
     public String getText() {
           return text;
     }
     public void setText(String text) {
           this.text = text;
     }
     public String getHost() {
           return host;
     }
     public void setHost(String host) {
           this.host = host;
     }
     public int getPort() {
           return port;
     }
     public void setPort(int port) {
           this.port = port;
     }
     public Map<String, File> getInLineMap() {
           return inLineMap;
     }
     public void setInLineMap(Map<String, File> inLineMap) {
           this.inLineMap = inLineMap;
     }
      public String[] getCcArr() {
           return CcArr;
     }
     public void setCcArr(String[] ccArr) {
           CcArr = ccArr;
     }

 }

此工具类中主要重载了一些构造方法,使用的时候通过调用不同的构造传入不同的参数。发送邮件必须的几个参数是host,port,from,fromPwd,toArr/CcArr,所以当没有传入其中某个时,就会去配置文件中获取固定的参数。
通过SystemConfig工具类来获取config.properties中的参数,这个类是自己写的,详情请查询相关资料获取properties中数据,这里不再列出。

3.添加EmailUtil工具类方法
一切准备就绪,接下来就是创建工具类来发送邮件了。EmailUtil在上文中提到过,其中我们已经创建了一个方法getMailText来获取freemark模板文件

EmailUtil.java:
import java.io.File;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.mail.MailAuthenticationException;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.sun.mail.util.MailConnectException;

import freemarker.template.Template;

/**
 * 
 * @ClassName: EmailUtil
 * @Description: 邮件操作工具类
 * @author aggerChen
 * @date 2017年7月31日 上午10:16:15
 * @version 0.0.1
 */
public class EmailUtil{

    private static final int SUCC = 0;                        //成功                  //自定义的一些状态码,用于发生异常时返回
    private static final int FAIL = -1;                       //失败
    private static final int AUTHENTICATION  = -2;            //发送者身份验证异常
    private static final int CONNECT_ERR  = -3;               //网络异常
    private static final int NULL_MAIL  = -4;                 //收件人空指针异常


    /**
     * 
     * @MethodName: sendMailByFreeMarker
     * @Description: 通过FreeMarker模板发送邮件
     * @param config void 邮件配置文件
     */
    public static Result sendMailByFreeMarker(EmailConfig config) {                              //通过freeMark发送邮件,参数为我们定义的EmailConfig邮件参数类
        Result result = new Result(SUCC, "邮件发送成功!");
        try {
            JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
            mailSender.setHost(config.getHost());                         //设置Host
            mailSender.setPort(config.getPort());                         //设置Port
            mailSender.setUsername(config.getFrom());                     //设置发送者邮箱
            mailSender.setPassword(config.getFromPwd());                  //设置发送者邮箱密码
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true,"UTF-8");
            helper.setFrom(config.getFrom());
            String[] to = config.getToArr();     //收件人邮箱数组
            String[] Cc = config.getCcArr();     //抄送人邮箱数据
            if((to==null&&Cc==null)||(to.length<=0&&Cc.length<=0)){
                result.setResultCode(NULL_MAIL);
                result.setMsg("收件人和抄送人不能同时为空!");
                return result;
            }

            if(to!=null&&to.length>0) helper.setTo(to);        //接收
            if(Cc!=null&&Cc.length>0) helper.setCc(Cc);        //抄送
            helper.setSubject(config.getSubject());            //设置邮件主题
            helper.setText(config.getText(), true);            //设置邮件正文 第二个参数true,表示是否是html,我们的text是获取的模板html,所以为true
            //图片嵌入到html文件中
            Map<String,File> map = config.getInLineMap();      //邮件模板中有嵌入图片,请看邮件左上角的记事本图片。需要我们在这里配置。
            if(map!=null){
                for (String key : map.keySet()) {
                    helper.addInline(key, map.get(key));
                }
            }
            mailSender.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
            result.setMsg("邮件发送失败!");
            result.setResultCode(FAIL);
            return result;
        } catch (MailSendException e) {                         //邮件发送异常,里面包含了网络连接异常,邮箱地址错误异常,空指针异常等,所有获取异常信息,为用户返回更详细的异常信息
            e.printStackTrace();
            Exception ex = e.getMessageExceptions()[0];  
            if(ex instanceof MailConnectException){            //网络连接异常
                result.setResultCode(CONNECT_ERR);
                result.setMsg("网络连接异常!");
                return result;
            }else if(ex instanceof SendFailedException){       //邮箱地址错误异常.因为当收件人数组中只有有一个邮箱错误,则整个邮件就发不出去,这是我们不想看到的。我希望的是让他剔除错误的邮箱反馈给用户,而正确的邮箱则继续发送
                Address[] address = ((SendFailedException) ex).getInvalidAddresses();         //获取错误邮箱数组
                return removeErrMailResend(address, config);                                  //调用移除错误邮箱并重新发送邮件
            }else if(ex instanceof NullPointerException){
                result.setResultCode(NULL_MAIL);
                result.setMsg("收件人为空!");
                return result;
            }
        } catch (MailAuthenticationException e) {              //身份认证异常
            e.printStackTrace();
            result.setResultCode(AUTHENTICATION);
            result.setMsg("发件箱配置或密码错误!");
            return result;
        } catch (Exception e) {                                 //其他异常
            e.printStackTrace();
            result.setMsg("邮件发送失败!");
            result.setResultCode(FAIL);
            return result;
        }
        return result;
    }

    /**
     * 
     * @MethodName: getMailText
     * @Description: 获取邮件文本(通过加载FreeMarker模板HTML)
     * @param freemarkerConfig 配置文件
     * @param freemarkerFileName 模板名 eg: "classNotice.html"
     * @param map 模板动态数据值
     * @return
     * @throws Exception String
     */
    public static String getMailText(FreeMarkerConfigurer freemarkerConfig,
            String freemarkerFileName,Map<String,String> map) throws Exception {  
        // 通过指定模板名获取FreeMarker模板实例  
        Template template = freemarkerConfig.getConfiguration().getTemplate(freemarkerFileName);   
        // 解析模板并替换动态数据,最终content将替换模板文件中的${content}标签。  
        String htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);  
        return htmlText;  
    } 

    /**
     * 
     * @MethodName: removeErrMailResend
     * @Description: 移除错误邮箱并重新调用发送邮件
     * @param address 错误邮箱数组
     * @param config  邮件配置
     * @return Result 返回结果(result.result:错误邮箱数组)
     */
    private static Result removeErrMailResend(Address[] address,EmailConfig config){
        Result result = new Result();
        if(address==null||address.length<=0) return result; 
        String[] toArr = config.getToArr();
        String[] CcArr = config.getCcArr();
        for (int i=0,len=address.length;i<len;i++) {
            String a = address[i].toString();
            toArr = ArrayUtils.removeElement(toArr, a);
            CcArr = ArrayUtils.removeElement(CcArr, a);
        }
        config.setToArr(toArr);
        config.setCcArr(CcArr);
        Result newResult =  sendMailByFreeMarker(config);        //递归调用重新发送邮件
        result.setResultCode(newResult.getResultCode());
        result.setMsg(newResult.getMsg());
        result.setResult(address);                              //返回错误邮箱数组对象,提示前台用户
        return result;
    }

}

4.调用EmailUtil发送邮件
在上文controller的sendEmail方法中,我们已经获取模板到模板字符串,接下来就是发送邮件了, 加入如下代码:

ClassController.java:
import java.io.File;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import json.Result;
import json.SessionInfo;
import json.jfTableVO;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

/**
 *
 * @ClassName: ClassesController
 * @Description: 课程管理
 * @author aggerChen
 * @date 2017年4月10日 上午10:01:34
 */
@Controller
@RequestMapping("classes")
public class ClassesController extends BaseController{

     @Autowired
     private FreeMarkerConfigurer freemarkerConfig;                  //依赖注入spring-mvc.中配置的bean 邮件模板配置

     /**
      *
      * @MethodName: sendEmail
      * @Description: 发送邮件通知
      */
     @RequestMapping("/sendEmail")
     @ResponseBody
     public Result sendEmail(Long classId,String addr,String other,HttpServletRequest request,HttpSession session){
           Result result = new Result(-1, "通知邮件发送失败!");
           try {

          //获取项目当前web访问地址
          String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+request.getContextPath();

          //用Map存储变量名和变量值映射,用于注入模板中${}引用的变量
          Map<String, String> map = new HashMap<>();
          map.put("className", "关于拉格朗日中值定理与牛顿-莱布尼茨公式在日常代码中的应用会议");                //会议名
          map.put("classDate", "2017-08-30 15:23:00");                                                 //会议时间
          map.put("classAddr", "会议室");                       //会议地点
          map.put("classScore", 5);                            //会议积分
          map.put("author", "管理员");                          //邮件作者
          map.put("classDesc", "描述描述描述");                  //描述
          map.put("other", "无");                              //其他
          map.put("url", "http://www.xxx.com");                //项目访问地址

          //调用工具类,传入参数生成模板String
          String text = EmailUtil.getMailText(freemarkerConfig, "classNotice.html", map);
         //生成text备用,以便后续传递给邮件发送。还有,模板中有一个图片,也需要我们注入,后面慢慢讲来
         
          EmailConfig config = new EmailConfig(toArr,CcArr, "会议通知", text);          //创建EmailConfig邮件配置类,传入我们的基本参数

          //图片嵌入到html文件中
          String path = this.getClass().getResource("/").getPath().replaceAll("WEB-INF/classes/", "");     //邮件模板左上角图片地址,因为是web项目,所以在WEB-INF下获取静态图片资源
          File file = new File(path+"dist/images/note.png");
          config.putInLineVal("note", file);                      //向配置中追加模板内嵌参数
          result = EmailUtil.sendMailByFreeMarker(config);        //调用邮件工具类静态方法发送邮件。返回result 是我们自定义的一个结果类,其中包含resultCode,resultObj,resultMsg三个属性。
         
     }
}
向邮件配置类中追加freemark模板内嵌图片,在模板中调用方式为
     <div style="background:url('cid:note') center no-repeat;"></div>
其中cid名与传入Map的key对应。如此一来就大功告成啦啦啦啦。。。。发送邮件还有更复杂的功能,例如发送附件等等,大同小异,有机会再弄吧。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章