<dependency>
<groupId>org.mnode.ical4j</groupId>
<artifactId>ical4j</artifactId>
<version>2.2.6</version>
</dependency>
直接通过maven下载下来的jar,会有时区问题,会导致用户收到的会议邀请邮件中显示的时间提前一个小时。解决方法:将ical4j-2.2.6.jar 中zoneinfo.Asia包下Shanghai.ics 文件修改。
jar包中Shanghai.ics文件内容:
BEGIN:VCALENDAR
PRODID:-//tzurl.org//NONSGML Olson 2018g-rearguard//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Asia/Shanghai
TZURL:http://tzurl.org/zoneinfo/Asia/Shanghai
X-LIC-LOCATION:Asia/Shanghai
BEGIN:STANDARD
TZOFFSETFROM:+080543
TZOFFSETTO:+0800
TZNAME:CST
DTSTART:19010101T000000
RDATE:19010101T000000
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+0800
TZOFFSETTO:+0900
TZNAME:CDT
DTSTART:19400601T000000
RDATE:19400601T000000
RDATE:19410315T000000
RDATE:19420131T000000
RDATE:19460515T000000
RDATE:19470415T000000
RDATE:19480501T000000
RDATE:19490501T000000
RDATE:19860504T020000
RDATE:19870412T020000
RDATE:19880417T020000
RDATE:19890416T020000
RDATE:19900415T020000
RDATE:19910414T020000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0900
TZOFFSETTO:+0800
TZNAME:CST
DTSTART:19401012T235959
RDATE:19401012T235959
RDATE:19411101T235959
RDATE:19450901T235959
RDATE:19460930T235959
RDATE:19471031T235959
RDATE:19480930T235959
RDATE:19490528T000000
RDATE:19860914T020000
RDATE:19870913T020000
RDATE:19880911T020000
RDATE:19890917T020000
RDATE:19900916T020000
RDATE:19910915T020000
END:STANDARD
END:VTIMEZONE
END:VCALENDAR
通过http://tzurl.org/zoneinfo/Asia/Shanghai 下载新的Shanghai.ics文件
内容如下:
BEGIN:VCALENDAR
PRODID:-//tzurl.org//NONSGML Olson 2016d//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Asia/Shanghai
TZURL:http://tzurl.org/zoneinfo-outlook/Asia/Shanghai
X-LIC-LOCATION:Asia/Shanghai
BEGIN:STANDARD
TZOFFSETFROM:+0800
TZOFFSETTO:+0800
TZNAME:CST
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
END:VCALENDAR
通过工具rar,直接用新的替换jar包中原有的Shanghai.ics文件
package com.example;
import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.TimeZone;
import net.fortuna.ical4j.model.TimeZoneRegistry;
import net.fortuna.ical4j.model.TimeZoneRegistryFactory;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.component.VTimeZone;
import net.fortuna.ical4j.model.parameter.Cn;
import net.fortuna.ical4j.model.parameter.Role;
import net.fortuna.ical4j.model.property.Attendee;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.property.Clazz;
import net.fortuna.ical4j.model.property.Description;
import net.fortuna.ical4j.model.property.Location;
import net.fortuna.ical4j.model.property.Method;
import net.fortuna.ical4j.model.property.Organizer;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Sequence;
import net.fortuna.ical4j.model.property.Uid;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.util.CompatibilityHints;
import net.fortuna.ical4j.util.FixedUidGenerator;
import com.sun.mail.smtp.SMTPTransport;
public class CalendarEmailSend {
private static final String SENDCLOUD_SMTP_HOST = "smtp.xx.xxxx";
private static final int SENDCLOUD_SMTP_PORT = 25;
public static String getUtc(String str){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long millionSeconds = 0;
try {
millionSeconds = sdf.parse(str).getTime();
} catch (ParseException e1) {
e1.printStackTrace();
}//毫秒
Date date = new Date(millionSeconds );
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化日期
String nowTime="";
nowTime= df.format(date);
String utcTime = nowTime.replace("-", "").replace(" ", "T").replace(":", "");//转换utc时间
return utcTime;
}
private static byte[] buildCalendar(Long startTime, Long endTime,
String summary, String organizerName, String organizerEmail,
String location, String participatorNames[],
String participatorEmails[], boolean isCancel, String suid)
throws Exception {
TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance()
.createRegistry();
TimeZone timezone = registry.getTimeZone("Asia/Shanghai");
VTimeZone tz = timezone.getVTimeZone();
DateTime start = new DateTime(startTime);
start.setTimeZone(timezone);
DateTime end = new DateTime(endTime);
end.setTimeZone(timezone);
VEvent meetingEvent = new VEvent(start, end, summary);
// 防止outlook或者是notes将日历当做附件使用增加的
CompatibilityHints.setHintEnabled(
CompatibilityHints.KEY_OUTLOOK_COMPATIBILITY, true);
CompatibilityHints.setHintEnabled(
CompatibilityHints.KEY_NOTES_COMPATIBILITY, true);
//CompatibilityHints.setHintEnabled(
// CompatibilityHints.KEY_RELAXED_UNFOLDING, true);
//CompatibilityHints.setHintEnabled(
// CompatibilityHints.KEY_RELAXED_PARSING, true);
//CompatibilityHints.setHintEnabled(
// CompatibilityHints.KEY_RELAXED_VALIDATION, true);
/** 添加时区信息 */
meetingEvent.getProperties().add(tz.getTimeZoneId());
/** 组织者 */
Organizer organizer = new Organizer(URI.create("mailto:"
+ organizerName));
organizer.getParameters().add(new Cn(organizerEmail));
meetingEvent.getProperties().add(organizer);
meetingEvent.getProperties().add(new Location(location));
/** 添加描述 */
meetingEvent.getProperties().add(new Description("description"));
/** 添加参与着 **/
if (participatorNames != null && participatorEmails != null) {
if (participatorEmails.length != participatorNames.length) {
throw new Exception("参与者名称与参与者邮箱要对应");
}
for (int i = 0; i < participatorNames.length; i++) {
Attendee dev = new Attendee(URI.create("mailto:"
+ participatorEmails[i]));
dev.getParameters().add(Role.REQ_PARTICIPANT);
dev.getParameters().add(new Cn(participatorNames[i]));
meetingEvent.getProperties().add(dev);
}
}
meetingEvent.getProperties().add(new Clazz("PUBLIC"));
/** 创建日历 */
Calendar icsCalendar = new Calendar();
icsCalendar.getProperties().add(
new ProdId("-//Events Calendar//iCal4j 1.0//EN"));
icsCalendar.getProperties().add(Version.VERSION_2_0);
icsCalendar.getProperties().add(CalScale.GREGORIAN);
icsCalendar.getComponents().add(tz);
Uid uid = null;
if (isCancel) {
uid = new Uid(suid);
meetingEvent.getProperties().add(uid);
meetingEvent.getProperties().add(new Sequence(2));
icsCalendar.getProperties().add(Method.CANCEL);
icsCalendar.getComponents().add(meetingEvent);
} else {
uid = new Uid(suid);
meetingEvent.getProperties().add(uid);
meetingEvent.getProperties().add(new Sequence(1));
icsCalendar.getProperties().add(Method.REQUEST);
icsCalendar.getComponents().add(meetingEvent);
}
CalendarOutputter co = new CalendarOutputter(false);
ByteArrayOutputStream os = new ByteArrayOutputStream();
co.output(icsCalendar, os);
byte[] mailbytes = os.toByteArray();
return mailbytes;
}
/**
*
* @param apiUser 用户
* @param apiKey 密码
* @param replyTo 回复地址
* @param names 参与者名字
* @param tos 参与者邮箱
* @param isCancel true 取消会议
* @param cancelUid 取消的会议 id
* @param gName 组织者名字
* @param gEmail 组织者邮箱
* @param start 会议开始时间
* @param end 结束时间
* @param method
* @return
* @throws Exception
*/
public static String sendCalender(final String apiUser,
final String apiKey, String replyTo, String names[], String tos[],
boolean isCancel, String cancelUid, String gName, String gEmail,
long start, long end, String method) throws Exception {
// 配置javamail
Properties props = System.getProperties();
props.setProperty("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", SENDCLOUD_SMTP_HOST);
props.put("mail.smtp.port", SENDCLOUD_SMTP_PORT);
props.setProperty("mail.smtp.auth", "true");
props.put("mail.smtp.connectiontimeout", 180);
props.put("mail.smtp.timeout", 600);
props.setProperty("mail.mime.encodefilename", "true");
Session mailSession = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(apiUser, apiKey);
}
});
SMTPTransport transport = (SMTPTransport) mailSession
.getTransport("smtp");
MimeMessage mimeMessage = new MimeMessage(mailSession);
mimeMessage.setSubject("会议邀请");
mimeMessage.setFrom(new InternetAddress("abc@web.sendcloud.net",
"xjm", "UTF-8"));
Uid uid = null;
if (isCancel) {
uid = new Uid(cancelUid);
} else {
uid = new FixedUidGenerator("uidGen").generateUid();
}
InternetAddress[] addressArray = new InternetAddress[tos.length];
for (int i = 0; i < tos.length; i++) {
addressArray[i] = new InternetAddress(tos[i]);
}
mimeMessage.addRecipients(Message.RecipientType.TO, addressArray);
// 日历
byte calendar[] = buildCalendar(start, end, "xjm日历", gName, gEmail,
"武汉", names, tos, isCancel, uid.toString().substring(4).trim());
String startTime="2020-02-16 15:00:00";
String endTime="2020-02-16 18:00:00";
startTime=getUtc(startTime);
endTime=getUtc(endTime);
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(calendar, "text/calendar;method="
+ method + ";charset=UTF-8")));
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
mimeMessage.setContent(multipart);
mimeMessage.saveChanges();
transport.connect();
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
transport.close();
return uid.toString().substring(4).trim();
}
public static void main(String[] args) throws Exception {
String apiUser = "xjm";
String apiKey = "xxxx";
String names[] = new String[] { "xjm" };
String toList[] = new String[] { "xjmfc@outlook.com" };
String replyTo = "reply@web.sendcloud.net";
String gName = "web";
String gEmail = "abc@web.sendcloud.net";
long start = System.currentTimeMillis();
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.add(java.util.Calendar.DAY_OF_MONTH, 3);
long end = cal.getTime().getTime();
//支持会议邀请、会议取消
String uid = sendCalender(apiUser, apiKey, replyTo, names, toList,false, null, gName, gEmail,start,end,"REQUEST");
}
}
https://web.sendcloud.net