注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

北漂的小羊

Java编程,开发者,程序员,软件开发,编程,代码。新浪微博号:IT国子监

 
 
 

日志

 
 
关于我

在这里是面向程序员的高品质IT技术学习社区,是程序员学习成长的地方。让我们更好地用技术改变世界。请关注新浪微博号: IT国子监(http://weibo.com/itguozijian)

网易考拉推荐

javamail实现发送会议邀请实例(使用ical4j和不使用ical4j版)  

2012-12-12 12:36:32|  分类: JAVA |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  新浪微博:IT国子监(记得关注噢) http://weibo.com/itguozijian


 iCal4j is a Java library used to read and write iCalendar data streams as defined in RFC2445. The iCalendar standard provides a common data format used to store information about calendar-specific data such as events, appointments, to-do lists, etc. All of the popular calendaring tools, such as Lotus Notes, Outlook and Apple's iCal also support the iCalendar standard.


iCal4j用于读写iCalendar数据流的一组API。iCalendar标准提供了一种公共的数据格式用于存储关于日历方面的信息比如事件,约定,待办事项等。所有流行日历工具比如:Lotus Notes,Outlook和Apple的iCal都支持iCalendar标准。 


 (edit by king)最近要搞个提醒系统,也就是能够设置个时间,在那个时间发封邮件提醒的系统。为了能够更好的起到提醒的效果,暂定的方案是发送会议邀请。

    以前知道outlook的会议邀请格式不能仅仅发送ics附件,这样和outlook发送的会议邀请不太一样,不能默认自动加入到本地日历中,需要直接将ics格式当作正文发送。

    在网上找了下基于java的ical格式库,ical4j,用这个来创建ics格式文件。这个库的文档还算比较全,也有简单的例子,照着例子(http://wiki.modularity.net.au/ical4j/index.php?title=Examples#Creating_a_meeting_of_four_hour_duration )抄了一段代码,结果在outlook中显示不支持的ics格式。通过比对outlook发送的会议邀请邮件源代码,添加了icsCalendar.getProperties().add(Method.REQUEST);这个属性之后,终于能够在outlook中正常使用了。

    但是这样的会议邀请在我的kmail中,却总是提示不需要应答。在设置参与者的时候,明明已经把我自己的邮箱作为必选者了,但是还是不能对会议邀请进行响应。还是继续对比原来的会议邀请,发现在添加Attendee对象的时候,还可以增加好几个属性,如PARTSTAT,RSVP,经过多次尝试(哈哈,给别人发了n多垃圾邮件)后,终于在设置了RSVP属性(值为TRUE)的时候,kmail终于能够提示“您的应答已被请求”,可以应答这个邀请了。

    现在的代码:

Java代码 
  1. public static void sendEventEmail(List<Pair<String, String>> reqs,  
  2.             List<Pair<String, String>> opts, Date startTime, Date endTime,  
  3.             String location, String name, String content)  
  4.             throws IOException, ValidationException, IllegalArgumentException {  
  5.         if (reqs == null || reqs.isEmpty()) {  
  6.             throw new IllegalArgumentException(  
  7.                     "Required participant should not be empty!");  
  8.         }  
  9.         List<String> tos = new ArrayList<String>();  
  10.           
  11.         DateTime start = new DateTime(startTime);  
  12.         DateTime end = new DateTime(endTime);  
  13.         VEvent meeting = new VEvent(start, end, name);  
  14.         TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance()  
  15.                 .createRegistry();  
  16.         // 设置时区  
  17.         TimeZone timezone = registry.getTimeZone("Asia/Shanghai");  
  18.         VTimeZone tz = timezone.getVTimeZone();  
  19.         meeting.getProperties().add(tz.getTimeZoneId());  
  20.   
  21.         meeting.getProperties().add(new Location(location));  
  22.         meeting.getProperties().add(new Summary(name));  
  23.         meeting.getProperties().add(new Description(content));  
  24.   
  25.         // 设置uid  
  26.         UidGenerator ug;  
  27.         Uid uid;  
  28.         ug = new UidGenerator("uidGen");  
  29.         uid = ug.generateUid();  
  30.         meeting.getProperties().add(uid);  
  31.         for (Pair<String, String> participant : reqs) {  
  32.             Attendee attendee = new Attendee(URI.create("mailto:"  
  33.                     + participant.first()));  
  34.             attendee.getParameters().add(Role.REQ_PARTICIPANT);  
  35.             attendee.getParameters().add(PartStat.NEEDS_ACTION);  
  36.             attendee.getParameters().add(Rsvp.TRUE);  
  37.             attendee.getParameters().add(new Cn(participant.second()));  
  38.             meeting.getProperties().add(attendee);  
  39.             tos.add(participant.first());  
  40.         }  
  41.   
  42.         if (opts != null && !opts.isEmpty()) {  
  43.             for (Pair<String, String> participant : opts) {  
  44.                 Attendee attendee = new Attendee(URI.create("mailto:"  
  45.                         + participant.first()));  
  46.                 attendee.getParameters().add(Role.OPT_PARTICIPANT);  
  47.                 attendee.getParameters().add(new Cn(participant.second()));  
  48.                 meeting.getProperties().add(attendee);  
  49.                 tos.add(participant.first());  
  50.             }  
  51.         }  
  52.   
  53.         Calendar icsCalendar = new Calendar();  
  54.         icsCalendar.getProperties().add(  
  55.                 new ProdId("-//Events Calendar//iCal4j 1.0//EN"));  
  56.         icsCalendar.getProperties().add(Version.VERSION_2_0);  
  57.         icsCalendar.getProperties().add(Method.REQUEST);  
  58.         icsCalendar.getComponents().add(meeting);  
  59.           
  60.         CalendarOutputter co = new CalendarOutputter(false);  
  61.         Writer wtr = new StringWriter();  
  62.         co.output(icsCalendar, wtr);  
  63.         String mailContent = wtr.toString();  
  64.           
  65.         sendEmail(tos, name, mailContent);  
  66. }  

 其中sendEmail方法就是通过javamail发送邮件:

Java代码 
  1. public static void sendEmail(List<String> tos, String subject, String content) {  
  2.         Properties properties = new Properties();  
  3.         properties.put("mail.transport.protocol""smtp");  
  4.         properties.put("mail.smtp.user""xxx");  
  5.         properties.put("mail.smtp.host""xxx");  
  6.         properties.put("mail.smtp.port""xxx");  
  7.         properties.put("mail.smtp.auth""true");  
  8.   
  9.         final String username = "xxx";  
  10.         final String password = "xxx";  
  11.         Authenticator authenticator = new Authenticator() {  
  12.             protected PasswordAuthentication getPasswordAuthentication() {  
  13.                 return new PasswordAuthentication(username, password);  
  14.             }  
  15.         };  
  16.   
  17.         Transport transport = null;  
  18.   
  19.         try {  
  20.             Session session = Session.getDefaultInstance(properties,  
  21.                     authenticator);  
  22.             MimeMessage mimeMessage = new MimeMessage(session);  
  23.             mimeMessage.setSubject(subject);  
  24.               
  25.             for(String to : tos) {  
  26.                 mimeMessage.addRecipient(Message.RecipientType.TO,  
  27.                         new InternetAddress(to));  
  28.             }  
  29.               
  30.             mimeMessage.setFrom(new InternetAddress(  
  31.                     "xxx@xxx.com"));  
  32.   
  33.             mimeMessage.setContent(content,  
  34.                     "text/calendar;method=REQUEST;charset=UTF-8");  
  35.   
  36.             transport = session.getTransport();  
  37.             transport.connect(username, password);  
  38.             transport.sendMessage(mimeMessage, mimeMessage  
  39.                     .getRecipients(javax.mail.Message.RecipientType.TO));  
  40.         } catch (MessagingException e) {  
  41.             // TODO Auto-generated catch block  
  42.             e.printStackTrace();  
  43.         } finally {  
  44.             if (transport != null)  
  45.                 try {  
  46.                     transport.close();  
  47.                 } catch (MessagingException logOrIgnore) {  
  48.                 }  
  49.         }  
  50.     }  

     现在还发现的问题是:

  1. 没有设置组织者,不过这个修改起来还是比较方便的
  2. 没有增加提醒,这个需要在calendar对象中添加VAlarm,增加提醒
  3. 还不支持html格式,这个再说了,作为一个提醒,应该不需要很绚的内容
下面是没有使用ical4j的方法实现:

关于icalendar的规范,请看:https://rsync.tools.ietf.org/html/rfc5545

Java代码 
  1. public class Email {  
  2.     private static String EMAIL_CONFIG = "email_config.properties";  
  3.     private Properties emailProp = new Properties();  
  4.     public Email() {  
  5.         InputStream is = getClass().getResourceAsStream("/"+EMAIL_CONFIG);  
  6.         try {  
  7.             emailProp.load(is);  
  8.         } catch (IOException e) {  
  9.             // TODO Auto-generated catch block  
  10.             e.printStackTrace();  
  11.         }  
  12.     }  
  13.   
  14.     private class EmailAuthenticator extends Authenticator {  
  15.         protected PasswordAuthentication getPasswordAuthentication() {  
  16.             String userId = emailProp.getProperty("userId""");  
  17.             String password = emailProp.getProperty("password""");  
  18.             return new PasswordAuthentication(userId, password);  
  19.         }  
  20.     }  
  21.   
  22.     public void send() throws Exception {  
  23.   
  24.         try {  
  25.             String fromEmail = emailProp.getProperty("fromEmail""");  
  26.             String toEmail=emailProp.getProperty("toEmail""");   
  27.             Properties props = new Properties();  
  28.             try {  
  29.                 props.put("mail.smtp.port""587");  
  30.                 props.put("mail.smtp.host""smtp.gmail.com");  
  31.                 props.put("mail.transport.protocol""smtp");  
  32.                 props.put("mail.smtp.auth""true");  
  33.                 props.put("mail.smtp.starttls.enable""true");  
  34.                 props.put("mail.smtp.ssl""true");  
  35.   
  36.             } catch (Exception e) {  
  37.                 e.printStackTrace();  
  38.             }  
  39.   
  40.             Session session;  
  41.             Authenticator authenticator = new EmailAuthenticator();  
  42.             session = Session.getInstance(props, authenticator);  
  43.             MimeMessage message = new MimeMessage(session);  
  44.             message.setFrom(new InternetAddress(fromEmail));  
  45.             message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));  
  46.             message.setSubject("Outlook Meeting Request Using JavaMail");  
  47.             StringBuffer buffer = new StringBuffer();  
  48.             buffer.append("BEGIN:VCALENDAR\n"  
  49.                     + "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"  
  50.                     + "VERSION:2.0\n"  
  51.                     + "METHOD:REQUEST\n"  
  52.                     + "BEGIN:VEVENT\n"  
  53.                     + "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+toEmail+"\n"  
  54.                     + "ORGANIZER:MAILTO:"+toEmail+"\n"  
  55.                     + "DTSTART:20120302T060000Z\n"  
  56.                     + "DTEND:20120302T070000Z\n"  
  57.                     + "LOCATION:Conference room\n"  
  58.                     + "UID:"+UUID.randomUUID().toString()+"\n"//如果id相同的话,outlook会认为是同一个会议请求,所以使用uuid。  
  59.                     + "CATEGORIES:SuccessCentral Reminder\n"  
  60.                     + "DESCRIPTION:This the description of the meeting.<br>asd;flkjasdpfi\n\n"  
  61.                     + "SUMMARY:Test meeting request\n" + "PRIORITY:5\n"  
  62.                     + "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"  
  63.                     + "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"  
  64.                     + "DESCRIPTION:Reminder\n" + "END:VALARM\n"  
  65.                     + "END:VEVENT\n" + "END:VCALENDAR");  
  66.             BodyPart messageBodyPart = new MimeBodyPart();  
  67.             // 测试下来如果不这么转换的话,会以纯文本的形式发送过去,  
  68.             //如果没有method=REQUEST;charset=\"UTF-8\",outlook会议附件的形式存在,而不是直接打开就是一个会议请求  
  69.             messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(buffer.toString(),   
  70.                     "text/calendar;method=REQUEST;charset=\"UTF-8\"")));  
  71.             Multipart multipart = new MimeMultipart();  
  72.             multipart.addBodyPart(messageBodyPart);  
  73.             message.setContent(multipart);  
  74.             Transport.send(message);  
  75.         } catch (MessagingException me) {  
  76.             me.printStackTrace();  
  77.         } catch (Exception ex) {  
  78.             ex.printStackTrace();  
  79.         }  
  80.     }  
  81.       
  82.     public static void main(String[] args) {  
  83.         try {  
  84.             Email email = new Email();  
  85.             email.send();  
  86.             System.out.println("success");  
  87.         } catch (Exception e) {  
  88.             e.printStackTrace();  
  89.         }  
  90.     }  
  91.   


  评论这张
 
阅读(3269)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016