zoukankan      html  css  js  c++  java
  • Java系列--第四篇 基于Maven的SSME之发送邮件

    系列第一篇中,使用的是mybatis得到了一个小小的项目,而该项目的用户对象是有邮件地址的,如果按照邮件地址给对方去一封邮件会不会更能体现针对性呢,所以,我在这篇准备加入发送邮件的功能,利用的就是spring 自带的JavaMail.

    1, 更新pom.xml. 添加velocity,javax.mail1.5能及spring-context-support.

    <dependency>
        <groupId>velocity</groupId>
        <artifactId>velocity</artifactId>
        <version>1.5</version>
    </dependency>
    velocity1.5
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.5.0</version>
    </dependency>
    javax.mail1.5.0
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>3.2.4.RELEASE</version>
    </dependency>
    spring-context-support3.2.4-RELEASE

    2, 新建emailtemplates文件夹,包含vm和jpg文件。因为我的邮件要包含logo的。邮件里面要包含图片显示,vm模板必须写成<img src="cid:图片服务器端全地址,如本例中使用logoName"/>,发送时

    org.springframework.core.io.Resource img = new ClassPathResource(logoName);
    message.addInline("logoName", img);

    3, config.properties中加入

    com.vanceinfo.emailtemplate/myEmail=emailtemplates/myEmail.vm
    com.vanceinfo.emailtemplate/myEmaillogo=emailtemplates/FlyingBird.jpg

    4,spring-mvc.xml中加入

    <!-- spring mail send configuration -->
        <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <property name="host" value="smtp.gmail.com" />
            <property name="port" value="587" />
            <property name="username" value="kingnaliu@gmail.com" />
            <property name="password" value="you real password" />
            <property name="javaMailProperties">  
                <props>  
                    <prop key="mail.smtp.starttls.enable">true</prop>
                </props>  
            </property>   
        </bean>
    
        <bean id="restTemplate" class="org.springframework.web.client.RestTemplate" />
    
        <bean id="velocityEngine"
            class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
            <property name="velocityProperties">
                <value>
                    resource.loader=class
                    class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
                </value>
            </property>
        </bean>
    spring mail send configuration

    5,然后就是Java代码,分别定义一个接口,接品实现类及一个辅助实现的Helper类。这里有一个设计上的缺陷就是为了写单元测试,新开线程时写了一个实名的Runnable的类,本来用Java匿名类来实现是很优雅的一件事情,偏偏为了追求单元测试的覆盖率而白白增加这个Runnable类,而且还要在里面注入所需的参数和service名称。感觉有点搞。所以,我还是贴出我最原始的Helper类的源码吧。

    package com.vanceinfo.javaserial.services;
    
    import javax.mail.MessagingException;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.vanceinfo.javaserial.model.EmailInfo;
    import com.vanceinfo.javaserial.model.User;
    
    @Service("sendEmailHelper")
    public class SendEmailHelper {
    
        @Autowired
        private ISendEmail sendEmailService;
    
        public void sendVMLogoEmail(final User user) {
            /*
             * SendVMLogoEmailRunnable runnable = new SendVMLogoEmailRunnable();
             * runnable.setSendEmailService(sendEmailService);
             * runnable.setUser(user); Thread sendEmailThread = new
             * Thread(runnable); sendEmailThread.start();
             */
            new Thread(new Runnable() {
                public void run() {
                    try {
                        EmailInfo email = new EmailInfo();
                        email.setFrom("jinliangliu@163.com");
                        email.setTo(new String[] { user.getEmail() });
                        email.setSubject("Test");
                        email.setEmailPlaceHolder(user);
                        email.setTempleteName("emailtemplates/myEmail.vm");
                        sendEmailService.sendEmailWithTemplate(email);
                    } catch (MessagingException e) {
    
                    } catch (Exception e) {
    
                    }
    
                }
            }).start();
        }
    }
    SendEmailHelper

    6,最后,我是在userService里面调用Helper,让Helper调用实现类完成发送邮件功能。为什么要用Helper,因为如果你还要发送其也类型的邮件,只需在这里加入方法即可完成。

    7, 上面提到的单元测试覆盖率,我们项目使用的是EclEmma,这个插件可以直接以EclEmma在Eclipse市场查找到,安装完之后,即可使用,其写方网址是:http://www.eclemma.org/

    8,添加单元测试。这次我准备用一个tokenHandler来完成这次单元测试。因为要自定义Token的tag,所以先引入javax.servlet.jsp-api

    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    javax.servlet.jsp-api2.3.1

     作这个token的作用,是我不想每次按F5或Ctrl+F5的时候,重新发送请求,也就是常说的二次提交问题的避免。中心思想来源于Struts2的token就是说当用户加载这个页面时,这个token生成了一个Guid,分别保存进session和hidden两个地方。提交之前对这两个进行比较,内容完全一致则认为是一致的,提交上去,然后remove掉session里面的Guid,这样子话,如果用户再次提交,就会因为session里面为空,而hidden里面还有值而不一致,跳转页面不让提交。

    在spring-mvc.xml中加入声明:

    <mvc:interceptors>
        <!-- use Token to void multi post when user press F5 or Ctrol+F5 -->
        <mvc:interceptor>
            <mvc:mapping path="/index.do" />
            <bean
                    class="com.vanceinfo.javaserial.handlerinterceptors.TokenHandlerInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
    mvc:interceptor

     由于我更改了spring-mvc.xml里面对模型视图的解析,由原来的

    <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver"
            p:prefix="/" p:suffix=".jsp" />

    变成了如下:

    <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/jsp/" />
        <property name="suffix" value=".jsp" />
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
    </bean>
    对模型视图名称的解析

    所以还要加上jstl-api1.2.1

    <dependency>
        <groupId>javax.servlet.jsp.jstl</groupId>
        <artifactId>javax.servlet.jsp.jstl-api</artifactId>
        <version>1.2.1</version>
    </dependency>
    javax.servlet.jsp.jstl-api1.2.1

    如果不知道如何自定义jsp标签的话,可以参考这里,我这里的步骤:a,定义tag类,让其扩展TagSupport类. b,在WEB-INF下面创建标签库描述文件.tld(Tag Library Description). c,在web.xml里面定义

    <jsp-config>
            <taglib>
                <taglib-uri>/mytaglib</taglib-uri>
                <taglib-location>/WEB-INF/tlds/Token.tld</taglib-location>
            </taglib>
      </jsp-config>
    配置自定义标签

    d,在需引用的jsp里声明:

    <%@ taglib uri="/mytaglib" prefix="ck"%>

    并写上

    <ck:token/>

    即可。

    值得一提的是这次的单元测试,还是使用的是参数化单元测试的,当写到这里的时候,我想还是另开一篇专门讲这一小节的好了。请点击这里

    9,修改后的源码我更新了,可以在这里下载到

  • 相关阅读:
    Sql题目精选练习
    SqlServer2008数据库的备份与还原
    SqlServer视图介绍以及创建方式
    Java反射详解
    for(foo('a') ; foo('b') && (i<2);foo('c'))的执行结果
    jdk与jre与jdk都是干什么的有什么区别和jvm详解:
    List去重为什么要写equals(),hashCode()方法
    String类的常用方法以及知识点总结
    o enclosing instance of type ArrayList_day02 is accessible. Must qualify the allocation with an enclosing instance of type ArrayList_day02
    JAVA整理01--面向对象基础
  • 原文地址:https://www.cnblogs.com/SLKnate/p/Java_Serial_SSME_SendEmail.html
Copyright © 2011-2022 走看看