最近做了一个项目,要根据客户定制的任务信息发日历提醒信息,上网查了些资料,发现网上的资料有些不全,这对于初次接触这个技术的人来说是件很麻烦的事,所以把代码分享一下,希望对大家有所帮助。
发送日历提醒有两种方式 ,一种通过纯文本方式,一种是通过iCal4j 自动生成一个提醒时间,不管哪种方式,都要有一下几个元素
BEGIN:VCALENDAR ------ 起始 VERSION:2.0 ------ 版本 PRODID:iCal4j v1.0//EN ------ 创建该对象的标志符 BEGIN:VEVENT ------ 事件开始 DTSTART:19970714T170000Z ------ 事件起始时间 DTEND:19970715T040000Z ------ 事件结束时间 SUMMARY:Bastille Day Party ------ 事件概要 END:VEVENT ------ 事件结束 END:VCALENDAR ------ 结束
上面的例子,它表示发生在 1997 年七月十四日下午五点与 1997 年七月十五日四点之间的事件“Bastille Day Party”。
较为详细的资料可以参考 iCalendar 编程基础:了解和使用 iCal4j 这篇文章。
下面我们通过代码来讲解
首先 需要几个jar 包 mail.jar(生成邮件的),ical4j-1.0.jar
下面是完整的java 代码
这个 类 是生成提醒时间的类
SalesFollowupScheduleImpl.java
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.net.SocketException;
import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import net.fortuna.ical4j.data.CalendarOutputter;
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.ValidationException;
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.PartStat;
import net.fortuna.ical4j.model.parameter.Role;
import net.fortuna.ical4j.model.parameter.Rsvp;
import net.fortuna.ical4j.model.property.Attendee;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.property.Created;
import net.fortuna.ical4j.model.property.Location;
import net.fortuna.ical4j.model.property.Method;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Uid;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.util.UidGenerator;
import org.apache.log4j.Logger;
import com.m3td.m3ssi.bussion.email.MailSendCustomerManagerImpl;
import com.m3td.m3ssi.common.util.FileUtil;
import com.m3td.m3ssi.entity.sales.SalesFollowupBean;
/**
* Sales Person 任务日程提醒(生成ICS)
*
* @author jet
* @time 2012-12-13
*
*/
public class SalesFollowupScheduleImpl {
private static final Logger log = Logger
.getLogger(SalesFollowupScheduleImpl.class);
//创建日历
public void createEvent(SalesFollowupBean salesFollowupBean) throws ParseException, IOException, ValidationException{
if(salesFollowupBean!=null)
{
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date startDateV = new Date();
String date = salesFollowupBean.getTask_fulltime();
String content = salesFollowupBean.getTask_content();
startDateV = sdf.parse(date);
//创建时区
TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
//设置时区
TimeZone timezone = registry.getTimeZone("America/Mexico_City");
VTimeZone tz = timezone.getVTimeZone();
// Start Date
java.util.Calendar startDate = new GregorianCalendar();
startDate.setTimeZone(timezone);
startDate.setTime(startDateV);
// End Date
java.util.Calendar endDate = new GregorianCalendar();
endDate.setTimeZone(timezone);
endDate.setTime(startDateV);
//Create the event
String eventName = salesFollowupBean.getTask_content();
DateTime start = new DateTime(startDate.getTime());
DateTime end = new DateTime(endDate.getTime());
VEvent meeting = new VEvent(start, end, eventName);
//add timezone info..
meeting.getProperties().add(tz.getTimeZoneId());
meeting.getProperties().add(new Location(""));//表里没有提醒地点,等以后有了添加上
meeting.getProperties().add(new Created("20121219T112146Z"));
//generate unique identifier..
UidGenerator ug = new UidGenerator("1");
Uid uid = ug.generateUid();
meeting.getProperties().add(uid);
//add attendees..
Attendee dev1 = new Attendee(URI.create("mailto:"+ salesFollowupBean.getCustomer_email()));
dev1.getParameters().add(Role.REQ_PARTICIPANT);
dev1.getParameters().add(Rsvp.TRUE);
dev1.getParameters().add(PartStat.NEEDS_ACTION);
dev1.getParameters().add(new Cn(content));
meeting.getProperties().add(dev1);
Attendee dev2 = new Attendee(URI.create("mailto:"+salesFollowupBean.getCustomer_email()));
dev1.getParameters().add(Role.REQ_PARTICIPANT);
dev1.getParameters().add(Rsvp.TRUE);
dev1.getParameters().add(PartStat.NEEDS_ACTION);
dev1.getParameters().add(new Cn(content));
meeting.getProperties().add(dev2);
//Create a calendar
net.fortuna.ical4j.model.Calendar icsCalendar = new net.fortuna.ical4j.model.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);
//Add the event and print
icsCalendar.getComponents().add(meeting);
CalendarOutputter co = new CalendarOutputter(false);
Writer wtr = new StringWriter();
co.output(icsCalendar, wtr);
//日历提醒文件转换问文本,做为邮件发送
String mailContent = wtr.toString();
//生成文件是否成功标示
boolean result = false;
//指定ics文件名称
String test = salesFollowupBean.getId()+"-"+salesFollowupBean.getSales_id();
// 生成ics文件
String dir = "d:/data/"; //晚点替换成变量 文件的生成格式
String fileName = test + ".ics";
String fileNamePath = dir+fileName;
result = FileUtil.writeEncodingFile("UTF-8", fileNamePath,
mailContent);
if(result==true){
log.debug("....生成ics文件成功....");
//send email
MailSendCustomerManagerImpl t = new MailSendCustomerManagerImpl();
t.sendMail(mailContent,fileNamePath,salesFollowupBean );
}
else
{
log.debug(".....生成ics文件失败.....");
}
}
//文本发送的方法
public StringBuffer createIcs() throws SocketException{
UidGenerator ug = new UidGenerator("1");
Uid uid = ug.generateUid();
StringBuffer buffer = new StringBuffer();
buffer.append("BEGIN:VCALENDAR\n"
+ "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
+ "VERSION:2.0\n"
+ "METHOD:REQUEST\n"
+ "BEGIN:VEVENT\n"
+ "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+"[email protected]"+"\n"
+ "ORGANIZER:MAILTO:"+"[email protected]"+"\n"
+ "DTSTART:20120302T060000Z\n"
+ "DTEND:20120302T070000Z\n"
+ "LOCATION:Conference room\n"
+ "UID:"+uid+"\n"//如果id相同的话,outlook会认为是同一个会议请求,所以使用uuid。
+ "CATEGORIES:SuccessCentral Reminder\n"
+ "DESCRIPTION:This the description of the meeting.
asd;flkjasdpfi\n\n"
+ "SUMMARY:Test meeting request\n" + "PRIORITY:5\n"
+ "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
+ "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"
+ "DESCRIPTION:Reminder\n" + "END:VALARM\n"
+ "END:VEVENT\n" + "END:VCALENDAR");
return buffer;
}
}
/**
* 客户信息发送,邮件处理类
*
* @author jet
* @time 2012-07-21
*
*/
public class MailSendCustomerManagerImpl {
private static Logger logger = Logger
.getLogger(MailSendCustomerManagerImpl.class);
@SuppressWarnings("static-access")
public void sendMail(String sendFile,String fileNamePath,SalesFollowupBean salesFollowupBean)
throws IOException {
logger.debug("==== com.m3td.m3spring.service.task.impl.MailSendCustomerManagerImpl.sendMailCustomerInfoForStaffManager() start====");
// 读取邮件配置信息
Properties perties = new Properties();
EmailSenderInfo mailSenderInfo = new EmailSenderInfo();
try {
// 获取邮件配置信息
InputStream inputStream = new BufferedInputStream(
new FileInputStream(this.getWebInfPath()+"/WEB-INF/resource.properties"));
perties.load(inputStream);
mailSenderInfo.setMailServerHost(perties.getProperty("email.server.host"));
mailSenderInfo.setTransport(perties.getProperty("email.server.transport"));
mailSenderInfo.setFromAddress(perties.getProperty("email.from.address"));
mailSenderInfo.setUserName(perties.getProperty("email.from.userName"));
mailSenderInfo.setPassword(perties.getProperty("email.from.userPassword"));
String toadderss[] = {salesFollowupBean.getCustomer_email()};// 多个邮件接收人 取customer info
String filesNames[] = {fileNamePath}; // 多个文件名 通过sales
// 正文
mailSenderInfo.setContent(salesFollowupBean.getTask_content()); // content
// 主题
mailSenderInfo.setSubject(salesFollowupBean.getTask_content()); //content
// 接收人
mailSenderInfo.setToAddress(salesFollowupBean.getCustomer_email()); // 单个邮件接收人 ,取customer
mailSenderInfo.setToAddressArray(toadderss);
// 发送文件名称
mailSenderInfo.setFileName(fileNamePath); // 单个文件名 // 通过sales // id 和 // 客户名称生成
mailSenderInfo.setAttachFileNames(filesNames);
mailSenderInfo.setDoSend(true);
mailSendProccess(mailSenderInfo,sendFile); // 执行邮件发送
} catch (IOException ex) {
ex.printStackTrace();
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 执行邮件发送
*
* @param mailSenderInfo
* 邮件信息对象
* @throws IOException
*/
private void mailSendProccess(EmailSenderInfo mailSenderInfo,
String contextPath) throws IOException {
logger
.debug("==== com.m3td.m3spring.service.task.impl.MailSendCustomerManagerImpl.mailSendProccess() start====");
try {
// 设置邮件服务属性
Properties props = new Properties();
props.put("mail.smtp.host", mailSenderInfo.getMailServerHost());
props.put("email.server.transport", mailSenderInfo
.getMailServerPort());
props.put("mail.smtp.auth", "true");
// 根据属性新建一个邮件会话,消息对象
Session session = Session.getInstance(props);
session.setDebug(true);
MimeMessage message = new MimeMessage(session);
message.setSubject(mailSenderInfo.getSubject()); // 设置主题
message.setSentDate(new Date()); // 设置发信时间
message
.setFrom(new InternetAddress(mailSenderInfo
.getFromAddress()));// 设置发件人地址
message.setContent(contextPath,
"text/calendar;method=REQUEST;charset=UTF-8");
// 添加收件人地址
String[] mailToArray = mailSenderInfo.getToAddressArray();
if (mailToArray == null || mailToArray.length == 0) {
InternetAddress toAddress = new InternetAddress(mailSenderInfo
.getToAddress());
message.setRecipient(Message.RecipientType.TO, toAddress);
} else {
InternetAddress[] toAddressList = new InternetAddress[mailToArray.length];
for (int index = 0; index < mailToArray.length; index++) {
if (toAddressList != null && mailToArray[index] != null
&& (mailToArray[index].trim().length() > 0)) {
toAddressList[index] = new InternetAddress(
mailToArray[index]);
}
}
message.addRecipients(Message.RecipientType.TO, toAddressList);
}
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(
new ByteArrayDataSource(contextPath.toString(),
"text/calendar;method=REQUEST;charset=\"UTF-8\"")));
//设置正文
Multipart container = new MimeMultipart();
container.addBodyPart(messageBodyPart);
// Multipart container = new MimeMultipart();
// MimeBodyPart htmlContent = new MimeBodyPart();
// htmlContent.setText(contextPath);
// container.addBodyPart(htmlContent);
// message.setContent(container);
// 设置附件信息
MimeBodyPart fileBodyPart = null;
FileDataSource dataSource = null;
String[] fileNams = mailSenderInfo.getAttachFileNames();
if (fileNams != null && fileNams.length > 0) {
for (int index = 0; index < fileNams.length; index++) {
if (fileNams[index] != null
&& fileNams[index].trim().length() > 0) {
fileBodyPart = new MimeBodyPart();
dataSource = new FileDataSource(fileNams[index]);// 要发送的附件地址
fileBodyPart
.setDataHandler(new DataHandler(dataSource));
fileBodyPart.setFileName(dataSource.getName());// 设置附件的名称
container.addBodyPart(fileBodyPart);
}
}
message.setContent(container);// 设置附件内容
}
message.saveChanges();// 存储邮件信息
Transport tranSport = session.getTransport(mailSenderInfo
.getTransport());
tranSport.connect(mailSenderInfo.getMailServerHost(),
mailSenderInfo.getUserName(), mailSenderInfo.getPassword());
tranSport.sendMessage(message, message.getAllRecipients()); // 发送邮件
tranSport.close();
System.err.println("........邮件发送成功....");
} catch (MessagingException e) {
logger
.error("com.m3td.m3spring.service.task.impl.MailSendCustomerManagerImpl.mailSendProccess(MailSenderInfo mailSenderInfo)"
+ " 邮件发送失败:" + e.getMessage());
}
logger .debug("==== com.m3td.m3spring.service.task.impl.MailSendCustomerManagerImpl.mailSendProccess() end====");
}
//处理普通java类读取web-inf 下的文件路径问题
private String getWebInfPath(){
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
String path = url.toString();
int index = path.indexOf("WEB-INF");
if(index == -1){
index = path.indexOf("classes");
}
if(index == -1){
index = path.indexOf("bin");
}
path = path.substring(0, index);
if(path.startsWith("zip")){//当class文件在war中时,此时返回zip:D:/...这样的路径
path = path.substring(4);
}else if(path.startsWith("file")){//当class文件在class文件中时,此时返回file:/D:/...这样的路径
path = path.substring(6);
}else if(path.startsWith("jar")){//当class文件在jar文件里面时,此时返回jar:file:/D:/...这样的路径
path = path.substring(10);
}
try {
path = URLDecoder.decode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return path;
}
}