一、需求描述:
    
    日前,做了一个发送客户账单的功能,邮件模板采用自定义,生成vm文件,保存至redis,
    采用jodd-mail发送邮件,查询用户账单数据,账单明细,缓存加载模板并渲染数据,推送邮件至客户端.
    这里给大家推荐一下,jodd是一款很优秀的分类工具插件,邮件服务可以说是使用超级简单,
    但是性能很不错,实现代码干净利落;
    
二、Velocity的基本代码实现
  

 VelocityEngine ve = new VelocityEngine();
ve.setProperty(Velocity.INPUT_ENCODING, "utf-8");// 设置输入字符集
ve.setProperty(Velocity.OUTPUT_ENCODING, "utf-8");// 设置输出字符集
ve.init(); VelocityContext context = new VelocityContext();
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("name", "麦德漂");
result.put("age", "26")
context.put("map", result); //ve.evaluate(context, writer, "logTag", StringTemplate);
ve.evaluate(context, writer, "logTag", "第一列:$map.get('name'),第二列:$map.get('key')");
String content = writer.toString();
writer.close();

比较简单,如果缓存中没有模板内容,重新加载一遍

 VelocityContext context = new VelocityContext();
StringWriter writer = new StringWriter();
Template t = ve.getTemplate("/First.vm");
t.merge(context, writer);
String content = writer.toString();
writer.close();

  或者从本地文件去加载

 VelocityEngine ve = new VelocityEngine();
ve.setProperty(Velocity.RESOURCE_LOADER, "file");
ve.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "/test/test/template/");
ve.setProperty(Velocity.INPUT_ENCODING, "utf-8");
ve.setProperty(Velocity.OUTPUT_ENCODING, "utf-8");
ve.init();

三、采用jodd发送邮件

1.Jodd的流式编程:

 Email email = Email.create().from("...@jodd.org").to("...@jodd.org").subject("Hello!").addText("text").addHtml("<b>HTML</b> message...");

2.Jodd的邮件推送

 SmtpServer smtpServer = SmtpServer.create("mail.jodd.org").authenticateWith("user", "password");
SendMailSession session = smtpServer.createSession();
session.open();
session.sendMail(email1);
session.sendMail(email2);
session.close();

3.考虑到发送效率,避免进入垃圾箱,我目前每500封邮件关闭一次session,session中的邮件全部发送,保存发送记录,
      停顿10秒,失败时记录用户数据,支持失败重发.
      
四、关于统计邮件已读,未读

邮件发送出去,很多时候我们很在意用户是否已读,刚开始有两种思路:
    1.邮件设置已读回执,这种解决方案需要用户来触发,交互性不好,且统计不一定准确,直接放弃
    2.在邮箱内容中添加隐藏图片,很简单,如下:

 <img style='display:none;' src='" + countUrl + id + "'/>

这样用户在打开邮件时,会加载图片重新打到你的服务器,方便监控已读未读情况.
    
    注:在使用OutLook时,隐藏图片无法隐藏,最后我的统计路径输出了一张无色的java矢量图,当然很小,同样扔到redis了.

EDM推送的更多相关文章

  1. 在Openfire上弄一个简单的推送系统

    推送系统 说是推送系统有点大,其实就是一个消息广播功能吧.作用其实也就是由服务端接收到消息然后推送到订阅的客户端. 思路 对于推送最关键的是服务端向客户端发送数据,客户端向服务端订阅自己想要的消息.这 ...

  2. iOS---iOS10适配iOS当前所有系统的远程推送

    一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...

  3. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

     SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...

  4. SignalR SelfHost实时消息,集成到web中,实现服务器消息推送

    先前用过两次SignalR,但是中途有段时间没弄了,今天重新弄,发现已经忘得差不多了,做个笔记! 首先创建一个控制台项目Nuget添加引用联机搜索:Microsoft.AspNet.SignalR.S ...

  5. 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送

    微信支付之微信模板消息推送                    今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...

  6. Android 几种消息推送方案总结

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6241354.html 首先看一张国内Top500 Android应用中它们用到的第三方推送以及所占数量: 现 ...

  7. 基于SignalR的消息推送与二维码描登录实现

    1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于Singl ...

  8. fir.im Weekly - 关于 iOS10 适配、开发、推送的一切

    "小程序"来了,微信变成名副其实的 Web OS,新一轮的Web App 与Native App争论四起.程序员对新技术永远保持灵敏的嗅觉和旺盛的好奇心,@李锦发整理了微信小程序资 ...

  9. ASP.NET SignaiR 实现消息的即时推送,并使用Push.js实现通知

    一.使用背景 1. SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指 ...

随机推荐

  1. VS2013项目受源代码管理向源代码管理注册此项目时出错

    在使用TFS的时候有时出现无法加载项目,后来删除项目添加也是不行 编译项目的时候提示如题的错误,用记事本打开出错的几个项目的.csproj文件,把下面几行内容删掉就行了. <SccProject ...

  2. .net常見面試題(二)

    一.选择题 1. 下面叙述正确的是___C___. A.算法的执行效率与数据的存储结构无关 B.算法的空间复杂度是指算法程序中指令(或语句)的条数 C.算法的有穷性是指算法必须能在执行有限个步骤之后终 ...

  3. Bzoj 2141: 排队 分块,逆序对,树状数组

    2141: 排队 Time Limit: 4 Sec  Memory Limit: 259 MBSubmit: 1310  Solved: 517[Submit][Status][Discuss] D ...

  4. (DT系列一)DTS结构及其编译方法

    DTS结构及其编译方法 一:主要问题 1,需要了解dtsi与dts的关系 2,dts的结构模型 3,dts是如何被编译的,以及编译后会生成一个什么文件. 二:参考文字 1,DTS(device tre ...

  5. rtsp的东西

    http://ubuntuforums.org/showthread.php?t=1544946 http://www.live555.com/liveCaster/liveInput.html ht ...

  6. C++域宽设置

    域宽设置,域宽填充; 设置域宽, cout<<set[w-width](int n)<<被设置的输出内容 设置填充字符, cout<<setfill(char n) ...

  7. UVA 10557 XYZZY

    Problem D: XYZZY ADVENT: /ad�vent/, n. The prototypical computer adventure game, first designed by W ...

  8. hibernate.Session简介

    ★→→SessionFactory (org.hibernate.SessionFactory) 包含已经编译的映射(mappings),是制造session的工厂,可能含有一些可以在各个事务(tra ...

  9. 推荐一个可以直接在Visual Studio中看到complexity的插件CodeMaid

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:推荐一个可以直接在Visual Studio中看到complexity的插件CodeMaid.

  10. Jakarta-Commons- BeanUtils学习笔记:

    http://www.cnblogs.com/zhangyi85/archive/2009/04/22/1441341.html 1.什么是BeanUtils: BeanUtils主要提供了对于Jav ...