想要使用Java通过程序来实现发送日历邮件的功能有两种途径:一是调用ews(即Exchange WebService API)接口协议;二是通过第三方开源组件iCal4j来实现。其中通过iCal4j又可以分为两种形式:(1)通过自定义iCal4j中的各个组件使用iCalendar数据流生成*.ics文件,完事之后还要删除ics文件,比较麻烦,但是自定义性和灵活性强,功能丰富。(2)通过日历邮件协议定义的标准的文本格式来发送,形如:
String calendarContent = "BEGIN:VCALENDAR\n"
+ "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
+ "VERSION:2.0\n"
+ "METHOD:REQUEST\n"
+ "BEGIN:VEVENT\n"
//参会者
+ "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:xxxx@qq.com\n"
//组织者
//+ "ORGANIZER:MAILTO:张三\n"
+ "DTSTART:" + 开始时间 + "\n"
+ "DTEND:" + 结束时间 + "\n"
//地点
+ "LOCATION:会议室01\n"
//如果id相同的话,outlook会认为是同一个会议请求,所以使用uuid。
+ "UID:" + UUID.randomUUID().toString() + "\n"
+ "CATEGORIES:\n"
//描述
//+ "DESCRIPTION:Stay Hungry.<br>Stay Foolish.\n\n"
+ "SUMMARY:主题\n" + "PRIORITY:5\n"
+ "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
//提前10分钟提醒
+ "TRIGGER:-PT10M\n" + "ACTION:DISPLAY\n"
+ "DESCRIPTION:Reminder\n" + "END:VALARM\n"
+ "END:VEVENT\n" + "END:VCALENDAR"
使用ews还需要加载dll文件,较难上手,最后选择了文本格式发送。但是在发送过程中出现了乱码,我刚开始实在mac电脑本地调试,发送后去outlook中查看邮件内容和日历内容都正常,没有乱码,后来部署到云上即docker中就乱码了,乱码格式如下:
主要的乱码代码在这几个地方:
(1)标题处
刚开始我没有加 MimeUtility.encodeText()这个,加了以后主题就正常了,这是Javamail自带的字符集编码工具。
(2)邮件内容处
刚开始我没有加"UTF-8"设置字符集,加了以后邮件内容和日历内容就正常了。 当时怎么没想到setText还有第二个参数。一开始不知道setText的这个参数,一直想着给MimeMessage的setContent()方法添加mime类型(例如text/html;charset=utf-8),结果报了下面这个错:
Exception in thread "DataHandler.getInputStream" java.lang.ClassCastException: javax.mail.internet.MimeMultipart cannot be cast to java.lang.String
at org.apache.geronimo.mail.handlers.TextHandler.writeTo(TextHandler.java:141)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:869)
at javax.activation.DataHandler$1.run(DataHandler.java:251)
at java.lang.Thread.run(Thread.java:662)
因为我这是日历邮件,用的是MimeMultipart形式,日历也从某种形式上算一个附件,不能转成文本形式