package
lml;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeUtility;
import org.apache.log4j.Logger;
import common.Constants;
/**
* 这是一个解析邮件的工具类,不负责回显工作,与表示层无关<br>
* 主要的方法是:
* <ul>
* <li>判断一个邮件体是否附件</li>
* <li>判断一封邮件是否含有附件</li>
* <li>解析邮件的正文</li>
* </ul>
*
* @author M.Liang Liu
* @date 2007年5月25日16:08:40
*/
public class LmlMessage {
/**
* 得到邮件正文内容 邮件的正文可能是多种类型:
* <ul>
* <li> text/plain </li>
* <li> text/html</li>
* <li> multipart/alternative</li>
* <li> multipart/related:内有内嵌的文件,噢噢~</li>
* <li> mutilpart/* </li>
* <li> message/rfc822 </li>
* </ul>
*
* @param msg:待解析正文的邮件对象或邮件体(邮件的一部分)对象
* @author M.Liang Liu
* @version 1.0
* @since 1.6
* @return 根据邮件类型返回不同的邮件正文
*/
public static String getBody(Part part, String userName) {
Logger logger = Logger.getLogger("LmlMessage.java");
StringBuffer sb = new StringBuffer();
sb.append(new String(""));
try {
logger.debug("The type of the part is:" + part.getContentType());
/**
* 纯文本或者html格式的,可以直接解析掉
*/
if (part.isMimeType("text/plain") || part.isMimeType("text/html")) {
sb.append(part.getContent());
} else if (part.isMimeType("multipart/*")) {
/**
* 可供选择的,一般情况下第一个是plain,第二个是html格式的
*/
if (part.isMimeType("multipart/alternative")) {
Multipart mp = (Multipart) part.getContent();
int index = 0;// 兼容不正确的格式,返回第一个部分
if (mp.getCount() > 1)
index = 1;// 第2个部分为html格式的哦~
logger.debug("Now will choose the index(start from 0):"
+ index);
/**
* 已经根据情况进行了判断,就算不符合标准格式也不怕了.
*/
Part tmp = mp.getBodyPart(index);
sb.append(tmp.getContent());
} else if (part.isMimeType("multipart/related")) {
/**
* related格式的,那么第一个部分包含了body,里面含有内嵌的内容的链接.
*/
Multipart mp = (Multipart) part.getContent();
Part tmp = mp.getBodyPart(0);
String body = LmlMessage.getBody(tmp, userName);
int count = mp.getCount();
/**
* 要把那些可能的内嵌对象都先读出来放在服务器上,然后在替换相对地址为绝对地址
*/
for (int k = 1; count > 1 && k < count; k++) {
Part att = mp.getBodyPart(k);
String attname = att.getFileName();
attname = MimeUtility.decodeText(attname);
try {
File attFile = new File(
Constants.tomcat_AttHome_Key, userName
.concat(attname));
FileOutputStream fileoutput = new FileOutputStream(
attFile);
InputStream is = att.getInputStream();
BufferedOutputStream outs = new BufferedOutputStream(
fileoutput);
byte b[] = new byte[att.getSize()];
is.read(b);
outs.write(b);
outs.close();
} catch (Exception e) {
logger
.error("Error occurred when to get the photos from server");
}
String Content_ID[] = att.getHeader("Content-ID");
if (Content_ID != null && Content_ID.length > 0) {
String cid_name = Content_ID[0].replaceAll("<", "")
.replaceAll(">", "");
body = body.replaceAll("cid:" + cid_name,
Constants.server_attHome_Key.concat("/")
.concat(userName.concat(attname)));
}
}
sb.append(body);
return sb.toString();
} else {
/**
* 其他multipart/*格式的如mixed格式,那么第一个部分包含了body,用递归解析第一个部分就可以了
*/
Multipart mp = (Multipart) part.getContent();
Part tmp = mp.getBodyPart(0);
return LmlMessage.getBody(tmp, userName);
}
} else if (part.isMimeType("message/rfc822")) {
return LmlMessage
.getBody((Message) part.getContent(), userName);
} else {
/**
* 否则的话,死马当成活马医,直接解析第一部分,呜呜~
*/
Object obj = part.getContent();
if (obj instanceof String) {
sb.append(obj);
} else {
Multipart mp = (Multipart) obj;
Part tmp = mp.getBodyPart(0);
return LmlMessage.getBody(tmp, userName);
}
}
} catch (Exception e) {
return "解析正文错误!";
}
return sb.toString();
}
public static String getBody(Message msg, String userName) {
return LmlMessage.getBody((Part) msg, userName);
}
/**
* 判断一封邮件是否含有附件<br>
* 首先要满足:msg的mimetype是multipart/*类型的,然后要有某bodyPart的disposition是attachment
*
* @param msg:要判断是否含有附件的邮件
* @author M.Liang Liu
* @version 1.0
* @see public static boolean isAttachment(Part part)
* @return true:含有附件<br>
* false:不含有附件
*/
public static boolean hasAttachment(Message msg) {
Part part = (Part) msg;
try {
if (part.isMimeType("multipart/*")) {
Multipart mp = (Multipart) part.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++) {
Part tmp = mp.getBodyPart(i);
if (LmlMessage.isAttachment(tmp))
return true;
}
}
} catch (Exception e) {
return false;
}
return false;
}
/**
* 判断一个邮件体是否是附件<br>
* 核心代码主要是解析其头部的disposition,一般设置了是disposition是attachment的才是附件
*
* @author M.Liang Liu
* @version 1.0
* @return:如果是附件的话,那么返回true;<br>
* 否则/异常false;
*/
public static boolean isAttachment(Part part) {
try {
String disposition = part.getDisposition();
if ((disposition != null)
&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
.equals(Part.INLINE))))
return true;
} catch (Exception e) {
/**
* 上面的方法只是适合于附件不是中文,或者中文名较短的情况,<br>
* 附件中文名过长时就不能用了,因为javamail Api中的part.getDisposition()根本就不能得到正确的数据了<br>
* 捕获异常后,分别再详细判断处理
*/
String contentType = "";
try {
contentType = part.getContentType();
} catch (MessagingException e1) {
return false;
}
if (contentType.startsWith("application/octet-stream"))
return true;
return false;
}
return false;
}
}
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeUtility;
import org.apache.log4j.Logger;
import common.Constants;
/**
* 这是一个解析邮件的工具类,不负责回显工作,与表示层无关<br>
* 主要的方法是:
* <ul>
* <li>判断一个邮件体是否附件</li>
* <li>判断一封邮件是否含有附件</li>
* <li>解析邮件的正文</li>
* </ul>
*
* @author M.Liang Liu
* @date 2007年5月25日16:08:40
*/
public class LmlMessage {
/**
* 得到邮件正文内容 邮件的正文可能是多种类型:
* <ul>
* <li> text/plain </li>
* <li> text/html</li>
* <li> multipart/alternative</li>
* <li> multipart/related:内有内嵌的文件,噢噢~</li>
* <li> mutilpart/* </li>
* <li> message/rfc822 </li>
* </ul>
*
* @param msg:待解析正文的邮件对象或邮件体(邮件的一部分)对象
* @author M.Liang Liu
* @version 1.0
* @since 1.6
* @return 根据邮件类型返回不同的邮件正文
*/
public static String getBody(Part part, String userName) {
Logger logger = Logger.getLogger("LmlMessage.java");
StringBuffer sb = new StringBuffer();
sb.append(new String(""));
try {
logger.debug("The type of the part is:" + part.getContentType());
/**
* 纯文本或者html格式的,可以直接解析掉
*/
if (part.isMimeType("text/plain") || part.isMimeType("text/html")) {
sb.append(part.getContent());
} else if (part.isMimeType("multipart/*")) {
/**
* 可供选择的,一般情况下第一个是plain,第二个是html格式的
*/
if (part.isMimeType("multipart/alternative")) {
Multipart mp = (Multipart) part.getContent();
int index = 0;// 兼容不正确的格式,返回第一个部分
if (mp.getCount() > 1)
index = 1;// 第2个部分为html格式的哦~
logger.debug("Now will choose the index(start from 0):"
+ index);
/**
* 已经根据情况进行了判断,就算不符合标准格式也不怕了.
*/
Part tmp = mp.getBodyPart(index);
sb.append(tmp.getContent());
} else if (part.isMimeType("multipart/related")) {
/**
* related格式的,那么第一个部分包含了body,里面含有内嵌的内容的链接.
*/
Multipart mp = (Multipart) part.getContent();
Part tmp = mp.getBodyPart(0);
String body = LmlMessage.getBody(tmp, userName);
int count = mp.getCount();
/**
* 要把那些可能的内嵌对象都先读出来放在服务器上,然后在替换相对地址为绝对地址
*/
for (int k = 1; count > 1 && k < count; k++) {
Part att = mp.getBodyPart(k);
String attname = att.getFileName();
attname = MimeUtility.decodeText(attname);
try {
File attFile = new File(
Constants.tomcat_AttHome_Key, userName
.concat(attname));
FileOutputStream fileoutput = new FileOutputStream(
attFile);
InputStream is = att.getInputStream();
BufferedOutputStream outs = new BufferedOutputStream(
fileoutput);
byte b[] = new byte[att.getSize()];
is.read(b);
outs.write(b);
outs.close();
} catch (Exception e) {
logger
.error("Error occurred when to get the photos from server");
}
String Content_ID[] = att.getHeader("Content-ID");
if (Content_ID != null && Content_ID.length > 0) {
String cid_name = Content_ID[0].replaceAll("<", "")
.replaceAll(">", "");
body = body.replaceAll("cid:" + cid_name,
Constants.server_attHome_Key.concat("/")
.concat(userName.concat(attname)));
}
}
sb.append(body);
return sb.toString();
} else {
/**
* 其他multipart/*格式的如mixed格式,那么第一个部分包含了body,用递归解析第一个部分就可以了
*/
Multipart mp = (Multipart) part.getContent();
Part tmp = mp.getBodyPart(0);
return LmlMessage.getBody(tmp, userName);
}
} else if (part.isMimeType("message/rfc822")) {
return LmlMessage
.getBody((Message) part.getContent(), userName);
} else {
/**
* 否则的话,死马当成活马医,直接解析第一部分,呜呜~
*/
Object obj = part.getContent();
if (obj instanceof String) {
sb.append(obj);
} else {
Multipart mp = (Multipart) obj;
Part tmp = mp.getBodyPart(0);
return LmlMessage.getBody(tmp, userName);
}
}
} catch (Exception e) {
return "解析正文错误!";
}
return sb.toString();
}
public static String getBody(Message msg, String userName) {
return LmlMessage.getBody((Part) msg, userName);
}
/**
* 判断一封邮件是否含有附件<br>
* 首先要满足:msg的mimetype是multipart/*类型的,然后要有某bodyPart的disposition是attachment
*
* @param msg:要判断是否含有附件的邮件
* @author M.Liang Liu
* @version 1.0
* @see public static boolean isAttachment(Part part)
* @return true:含有附件<br>
* false:不含有附件
*/
public static boolean hasAttachment(Message msg) {
Part part = (Part) msg;
try {
if (part.isMimeType("multipart/*")) {
Multipart mp = (Multipart) part.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++) {
Part tmp = mp.getBodyPart(i);
if (LmlMessage.isAttachment(tmp))
return true;
}
}
} catch (Exception e) {
return false;
}
return false;
}
/**
* 判断一个邮件体是否是附件<br>
* 核心代码主要是解析其头部的disposition,一般设置了是disposition是attachment的才是附件
*
* @author M.Liang Liu
* @version 1.0
* @return:如果是附件的话,那么返回true;<br>
* 否则/异常false;
*/
public static boolean isAttachment(Part part) {
try {
String disposition = part.getDisposition();
if ((disposition != null)
&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
.equals(Part.INLINE))))
return true;
} catch (Exception e) {
/**
* 上面的方法只是适合于附件不是中文,或者中文名较短的情况,<br>
* 附件中文名过长时就不能用了,因为javamail Api中的part.getDisposition()根本就不能得到正确的数据了<br>
* 捕获异常后,分别再详细判断处理
*/
String contentType = "";
try {
contentType = part.getContentType();
} catch (MessagingException e1) {
return false;
}
if (contentType.startsWith("application/octet-stream"))
return true;
return false;
}
return false;
}
}