利用javamail、ical4j发送会议邀请(日历)邮件、注意ical4j需要修改

一、pom添加依赖        

<dependency>
            <groupId>org.mnode.ical4j</groupId>
            <artifactId>ical4j</artifactId>
            <version>2.2.6</version>
  </dependency>

二、修改ical4j 

      直接通过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文件

三、javamail与ical4j发送会议邀请、会议取消

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值