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,修改后的源码我更新了,可以在这里下载到。
Java系列--第四篇 基于Maven的SSME之发送邮件的更多相关文章
- Java系列--第五篇 基于Maven的SSME之Token及Parameterized单元测试
本来在第四篇要说完的,但是写着写着,我觉得内容有点多起来了,所以就另开这篇,在这里专门讲述Token的定义,JSP自定义标签以及如何用Parameterized的来做单元测试. 1,新建包com.va ...
- Java系列--第八篇 基于Maven的SSME之定时邮件发送
关于ssme这个我的小示例项目,想做到麻雀虽小,五脏俱全,看到很多一些web都有定时发送邮件的功能,想我ssme也加入一下这种功能,经查询相关文档,发现spring本身自带了一个调度器quartz,下 ...
- Java系列--第六篇 基于Maven的SSME之多国语言实现
如果你的网站足够强大,以致冲出了国门,走向了国际的话,你就需要考虑做多国语言了,不过,未雨绸缪,向来是我辈程序人员的优秀品质,谁知道那天,我们的网站被国外大公司看中收购,从而飞上枝头变凤凰.不扯这么多 ...
- Java系列--第三篇 基于Maven的Android开发CAIO
学习要打好基础,这里用一个项目来学习一下Android的组件,参考网址为这个但不限于这个.有些东西的学习,理解三遍理论还不如一遍操作,所谓理论来自实践,实践是检验真理的唯一标准.所以,虽然看懂了那篇文 ...
- Java系列--第七篇 基于Maven的Android开发实战项目
本篇是基于<Android应用案例开发大全,吴亚峰等著>的项目开发实例源码,其中有些图片,我做了一些修改,用于个人学习,请勿用于商业. 1, 日程管理专家 mvn archetype:ge ...
- 深入理解javascript作用域系列第四篇——块作用域
× 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...
- 前端工程师技能之photoshop巧用系列第四篇——图片格式
× 目录 [1]图片格式 [2]保存设置 前面的话 对于前端来说,图片格式是需要重要掌握的知识.本文是photoshop巧用系列第四篇——图片格式 图片格式 目前在前端的开发中常用的图片格式有jpg. ...
- 深入理解javascript作用域系列第四篇
前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...
- Java系列--第二篇 基于Maven的Android开发HelloAndroidWorld
曾经写过一篇Android环境配置的随笔,个人感觉特繁琐,既然有Maven,何不尝试用用Maven呢,经网上搜索这篇文章但不限于这些,而做了一个基于Maven的Android版的Hello Andro ...
随机推荐
- WebStorm 的使用(一)
WebStorm是一个捷克公司开发的,功能虽然很强大,但UI貌似一直不是东欧人的强项.WebStorm默认的编辑器颜色搭配不算讲究,我看习惯了VS2012的Dark Theme,再看这个顿觉由奢入俭难 ...
- 修改apk显示或隐藏桌面图标
反编译CM设置,打开AndroidManifest.xml,搜索“DEFAULT”,把他替换为"LAUNCHER",然后回编译,回编译之后签名在用RE放到system\app下该权 ...
- TimeZone 时区 (JS .NET JSON MYSQL)
来源参考 : http://www.cnblogs.com/qiuyi21/archive/2008/03/04/1089456.html 来源参考 : http://walkingice.blogs ...
- 【笔试&面试】C#中的程序集
1. C#中的程序集(Assembly) 答:程序集是包含一个或多个类型定义文件和资源文件的集合.它允许我们分离可重用类型的逻辑表示和物理表示. 程序集是一个可重用.可实施版本策略和安全策略 ...
- 动态共享库(so)开发精悍教程
动态共享库(so)开发精悍教程 翻译并根据实际情况进行了小小修改,仅关注Linux下动态共享库(Dynamic shared library .so)的开发. 1 简单的so实例 源文件 //test ...
- 设计模式 ( 十七 ):Observer 观察者模式 -- 行为型
1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信.但是 ...
- HDU4605---Magic Ball Game(主席树 好题)
题意:一颗二叉树,任意节点要么有两个孩子要么没孩子. 然后有一个球,从结点1开始往子孙结点走. 每碰到一个结点,有三种情况 如果此球重量等于该结点重量,球就停下了 如果此球重量小于该结点重量,则分别往 ...
- Nmon 监控 Linux 的系统性能
Nmon(得名于 Nigel 的监控器)是IBM的员工 Nigel Griffiths 为 AIX 和 Linux 系统开发的一款计算机性能系统监控工具.Nmon 可以把操作系统的统计数据展示在屏幕上 ...
- vb安装过程中 ntvdm.exe[9696]中发生未处理的win32异常
最近电脑总是出问题导致我的学习效率很低,前几天在用VB6.0的时候有个知识点不太熟悉,于是按F1发现不会出来帮助文档.突然想到重新装系统之后忘记了安装MSDN帮助插件,就在我安装这个软件的时候发现电脑 ...
- [转]ANDROID仿IOS微信滑动删除_SWIPELISTVIEW左滑删除例子
转载:http://dwtedx.sinaapp.com/itshare_290.html 本例子实现了滑动删除ListView的Itemdemo的效果.大家都知道.这种创意是来源于IOS的.左滑删除 ...