javamail+ical4j发送会议提醒
本篇讲述小编在使用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 Óû§ÎÞȨµÇ½:用户名密码错误