本篇讲述小编在使用ical4j时对其的理解与使用,留作笔记的同时希望能帮助到大家!
初学者可以先了解下ical4j的基本信息:
iCalender编程基础,了解与使用ical4j:https://www.ibm.com/developerworks/cn/java/j-lo-ical4j/index.html
废话不多说直接进入题
maven
<!-- 导入ical4j库 -->
<dependency>
<groupId>org.mnode.ical4j</groupId>
<artifactId>ical4j</artifactId>
<version>1.0.2</version>
</dependency>
<!-- 邮件start -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
在通过ical4j与javamail实现会议邀请的时候,过程如下
1、通过ical4j创建一个Calendar(日历),这个Calendar中可以包括VEvent(事件)、VAlarm(提醒)、TODO(待办事项)等多项内容。而会议邀请则必须要包含VEvent,如果需要提醒,则可以包含VAlarm。
public static Multipart getContentText() throws Exception {
// 时区
TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
TimeZone timezone = registry.getTimeZone("Asia/Shanghai");
// 会议地点
String location = "安徽省合肥市";
// 会议时间
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.setTimeZone(timezone);
//会议启动时间
cal.set(2018, 2 - 1, 13, 13, 45); // 月份是要早一个月
DateTime start = new DateTime(cal.getTime());
//会议结束时间
cal.set(2018, 2 - 1, 13, 18, 55);
DateTime end = new DateTime(cal.getTime());
// --------事件(VEvent start)----------
VEvent vevent = new VEvent(start, end, subject);
vevent.getProperties().add(timezone.getVTimeZone().getTimeZoneId());// 时区
vevent.getProperties().add(new Location(location));// 会议地点
vevent.getProperties().add(new Summary(subject));// 邮件主题
vevent.getProperties().add(new Description(content));// 邮件内容
vevent.getProperties().add(new UidGenerator("meeting invite").generateUid());// 设置uid
vevent.getProperties().add(new Organizer(URI.create("mailto:" + from)));
// 与会人
Set<String> emailSet = new HashSet<String>();
emailSet.add(from);
emailSet.add(to);
int i = 1;
for (String email : emailSet) {
Attendee attendee = new Attendee(URI.create("mailto:" + email));
if (1 == i) {
attendee.getParameters().add(Role.REQ_PARTICIPANT);
} else {
attendee.getParameters().add(Role.OPT_PARTICIPANT);
}
attendee.getParameters().add(new Cn("Developer" + i));
vevent.getProperties().add(attendee);
i++;
}
// --------VEvent Over----------
// --------提醒(VAlarm Start)----------
// 提前10分钟提醒
VAlarm valarm = new VAlarm(new Dur(0, 0, -10, 0));
// 重复一次
valarm.getProperties().add(new Repeat(1));
// 持续十分钟
valarm.getProperties().add(new Duration(new Dur(0, 0, 10, 0)));
// 提醒窗口显示的文字信息
valarm.getProperties().add(new Summary("Event Alarm"));
valarm.getProperties().add(Action.DISPLAY);
valarm.getProperties().add(new Description("Progress Meeting at 9:30am"));
vevent.getAlarms().add(valarm);// 将VAlarm加入VEvent
// --------VAlarm Over-------------
// --------日历对象 Start---------------
Calendar icsCalendar = new Calendar();
icsCalendar.getProperties().add(new ProdId("-//Events Calendar//iCal4j 1.0//EN"));
icsCalendar.getProperties().add(CalScale.GREGORIAN);
icsCalendar.getProperties().add(Version.VERSION_2_0);
icsCalendar.getProperties().add(Method.REQUEST);
icsCalendar.getComponents().add(vevent);// 将VEvent加入Calendar
// 将日历对象转换为二进制流
CalendarOutputter co = new CalendarOutputter(false);
ByteArrayOutputStream os = new ByteArrayOutputStream();
co.output(icsCalendar, os);
byte[] mailbytes = os.toByteArray();
// --------日历对象 Over------------------
BodyPart mbp = new MimeBodyPart();
mbp.setContent(mailbytes, "text/calendar;method=REQUEST;charset=UTF-8");
MimeMultipart mm = new MimeMultipart();
mm.setSubType("related");
mm.addBodyPart(mbp);
return mm;
}
2、事件创建之后,通过javamail发送邮件
private static String from = "***@126.com";
private static String to = "***@126.com";//收件人
private static String subject = "test";//标题
private static String content = "青空报告总结会议";//邮件内容
public static void main(String[] args) {
// 链接邮件服务器
Properties props = new Properties();
props.put("mail.transport.protocol", "smtp"); // 邮件协议
props.put("mail.smtp.host", "smtp.126.com"); // 服务器域名
props.put("mail.smtp.auth", "true");
//账号密码认证
Authenticator auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
String username = "***@126.com"; // 大多数是你邮件@前面的部分
String pwd = "******";
return new PasswordAuthentication(username, pwd);
}
};
Session mailSession = Session.getInstance(props, auth);
// 获取Message对象
Message msg = new MimeMessage(mailSession);
try {
// 设置邮件基本信息
msg.setFrom(new InternetAddress(from));//发件人
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));//收件人
msg.setSentDate(new java.util.Date());//发送时间
msg.setSubject(subject);//发送标题
Multipart mp = getContentText();// 获取不同类型的邮件的邮件内容
msg.setContent(mp);
msg.saveChanges();
} catch (Exception ex) {
}
System.out.println(sendEmail(msg));
}
public static Boolean sendEmail(Message msg) {
// 发送邮件
try {
Transport.send(msg);
return true;
} catch (SendFailedException e) {// 邮件地址无效
System.out.println(e);
return false;
} catch (Exception e) {
Timer timer = new Timer();
System.out.println(e);
return false;
}
}
使用javamail发送邮件时,需要连接邮件服务器,根据不同的邮箱填写不同的邮箱服务器域名及协议,具体可百度搜索相关邮箱网站即可查询
例:
网易126免费邮箱相关服务器服务器信息:
邮件服务器名称 | 服务器地址 | 端口号 |
POP3服务器 | pop.126.com | 110 |
SMTP服务器 | smtp.126.com | 25 |
IMAP服务器 | imap.126.com | 143 |
qq免费邮箱相关服务器服务器信息:
邮件服务器名称 | 服务器地址 | 端口号 |
POP3服务器 | pop.qq.com | 465 |
SMTP服务器 | smtp.qq.com | 587 |
在账号密码认证时,需要开通对应邮箱的授权码使用授权码代替邮箱密码
qq开通授权码流程:https://jingyan.baidu.com/article/fedf0737af2b4035ac8977ea.html
网易开通授权码流程:https://jingyan.baidu.com/article/9faa72318b76bf473c28cbf7.html
最后附加几条可能遇到的错误信息:
1、553 Mail from must equal authorized user:这个错误网上搜都说是System Admin e-main Address 没有设置,不过我后来解决是因为设置该属性的时候没有配置正确
mimeMessage.setFrom(new InternetAddress("***@126.com"));
2、535 Error: authentication failed:这个问题就是上面所说的授权码的问题了,如果你的pwssword 使用的是邮箱的登录密码就会报这个错误,需要获取邮箱的授权码才可以
3、javax.mail.NoSuchProviderException: No provider for pop:邮件协议与服务器域名冲突了,smtp => smtp.126.com,pop => pop.126.com
4、javax.mail.AuthenticationFailedException: 550 Óû§ÎÞȨµÇ½:用户名密码错误
5、com.sun.mail.smtp.SMTPSendFailedException: 554 DT:SPM 126 smtp1:如果出现改错误,那么可能是标题或内容中出现了test或helloword等,被网易认为邮件内容不合法。
把各项内容按正常的内容填写之后发送就正常使用了
具体可参考:
企业退信的常见问题:http://help.163.com/09/1224/17/5RAJ4LMH00753VB8.html