本篇讲述小编在使用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