使用javamail解析获取的邮件,当邮件正文中含有图片时,该如何解析?最好有demo!
补充当前解析类
@Service
public class AutoReadEmailServiceImpl extends BaseService<Question> implements AutoReadEmailService {
private static String POP3SERVER = "pop.exmail.qq.com";
private static String IMAPSERVER = "imap.exmail.qq.com";
@Resource
private SysUserDao sysUserDao;
@Resource
private QuestionDao questionDao;
@Resource
private QuestionAttachmentDao questionAttachmentDao;
@Resource
private SysUserEmailPWDDao sysUserEmailPWDDao;
@Value("${file.question.attachment.path}")
private String questionAttachmentPath;
public AutoReadEmailServiceImpl() {
}
// 自动获取邮件信息
@Override
public void aotuReadEmail() {
// 查询认证维护表中的认证信息,一般是获取接收邮箱的地址,密码和最后接收时间,此处只有一个
List<SysUserEmailPWD> queryResult = sysUserEmailPWDDao.doQueryAll();
if (queryResult != null && queryResult.size() > 0) {
for (SysUserEmailPWD epwd : queryResult) {
// 最后接收时间如果没有 默认给当前时间
Date latestReceiveTime = epwd.getLatestReceiveTime();
if(latestReceiveTime == null) {
latestReceiveTime = new Date();
}
SysUser sysUser = sysUserDao.get(epwd.getUserId());
if (StringUtils.isNotBlank(sysUser.getEmail())) {
receive(POP3SERVER, sysUser.getEmail(), epwd.getEmailpwd(), latestReceiveTime,
epwd, epwd.getUserId());
}
}
}
}
// 处理任何一种邮件都需要的方法
private void handle(Message msg, Question q) throws Exception {
q.setQuestionTitle(msg.getSubject());
q.setQuestionLastDealTime(msg.getSentDate());
}
@SuppressWarnings("unused")
private void saveAttach(Part part, Question q) throws Exception {
// 得到未经处理的附件名字
String fileName = MimeUtility.decodeText(part.getFileName());
String path = questionAttachmentPath;
new java.io.File(path).mkdir();
path = path + "//" + q.getQuestionId();
new java.io.File(path).mkdir();
InputStream in = part.getInputStream();
FileOutputStream writer = new FileOutputStream(new File(path + "//" + fileName));
byte[] content = new byte[255];
int read = 0;
while ((read = in.read(content)) != -1) {
writer.write(content);
}
QuestionAttachment qa = new QuestionAttachment();
qa.setQuestionId(q.getQuestionId());
qa.setFileName(fileName);
qa.setFilePath(path + "//" + fileName);
questionAttachmentDao.persist(qa);
writer.close();
in.close();
}
/**
* @param multipart // 接卸包裹(含所有邮件内容(包裹+正文+附件))
* @throws Exception
*/
private void reMultipart(Multipart multipart, Question q) throws Exception {
// 依次处理各个部分
for (int j = 0, n = multipart.getCount(); j < n; j++) {
Part part = multipart.getBodyPart(j);// 解包, 取出 MultiPart的各个部分, 每部分可能是邮件内容,
// 也可能是另一个小包裹(MultipPart)
// 判断此包裹内容是不是一个小包裹, 一般这一部分是 正文 Content-Type: multipart/alternative
if (part.getContent() instanceof Multipart) {
Multipart p = (Multipart) part.getContent();// 转成小包裹
// 递归迭代
reMultipart(p, q);
} else {
rePart(part, q);
}
}
}
/**
* @param part 解析内容
* @throws Exception
*/
private void rePart(Part part, Question q) throws Exception, UnsupportedEncodingException, IOException,
FileNotFoundException {
if (part.getDisposition() != null) {
saveAttach(part, q);
} else {
if (part.getContentType().startsWith("text/plain")) {
q.setQuestionContent(part.getContent().toString());
} else {
// System.out.println("HTML内容:" + part.getContent());
}
}
}
private void receive(String pop3Server, String username, String password, Date latestReceiveTime,
SysUserEmailPWD epwd, Long userId) {
try {
Date currentTime = new Date();
// 连接到邮件服务器并获得邮件
Properties prop = new Properties();
prop.put("mail.pop3.host", pop3Server);
Session session = Session.getDefaultInstance(prop);
Store store = session.getStore("pop3");
store.connect(pop3Server, username, password);
Folder inbox = store.getDefaultFolder().getFolder("INBOX");
// 设置inbox对象属性为可读写,这样可以控制在读完邮件后直接删除该附件
inbox.open(Folder.READ_WRITE);
Message[] msg = inbox.getMessages();
FetchProfile profile = new FetchProfile();
profile.add(FetchProfile.Item.ENVELOPE);
inbox.fetch(msg, profile);
for (int i = 0; i < msg.length; i++) {
if (msg[i].getSentDate().after(latestReceiveTime)) {
InternetAddress addr = (InternetAddress) msg[i].getFrom()[0];
InternetAddress[] cc = (InternetAddress[]) msg[i].getRecipients(Message.RecipientType.CC);
SysUser customer = sysUserDao.getByProerties("email", addr.getAddress());
if (customer != null && customer.getCustomerService() != null) {
Question q = new Question();
q.setQuestionStatus(QuestionParameters.STATUS_UNDISTRIBUTED);
q.setQuestionType("");
q.setQuestionCustomerServiceType(QuestionParameters.CUSTOMERSERVICETYPE_B);
q.setQuestionCustomerService(customer.getCustomerService());
q.setQuestionCustomer(String.valueOf(customer.getId()));
q.setQuestionCreateTime(new Date());
String ccaddr = "";
if (cc != null) {
for (int j = 0; j < cc.length; j++) {
String email = cc[j].getAddress();
if (email == null)
email = "";
else {
email = MimeUtility.decodeText(email);
}
String compositeto = email;
ccaddr += "," + compositeto;
}
ccaddr = ccaddr.substring(1);
}
q.setQuestionCc(ccaddr);
// 标记此邮件的flag标志对象的DELETED位为true,可以在读完邮件后直接删除该附件,具体执行时间是在调用
// inbox.close()方法的时候
msg[i].setFlag(Flags.Flag.DELETED, true);
handle(msg[i], q);
q = questionDao.generateQuestionId(q);
// getContent() 是获取包裹内容, Part相当于外包装
Object o = msg[i].getContent();
if (o instanceof Multipart) {
Multipart multipart = (Multipart) o;
reMultipart(multipart, q);
} else if (o instanceof Part) {
Part part = (Part) o;
rePart(part, q);
} else {
q.setQuestionContent(msg[i].getContent().toString());
}
questionDao.update(q);
}
epwd.setLatestReceiveTime(currentTime);
sysUserEmailPWDDao.merge(epwd);
}
}
if (inbox != null) {
// 参数为true表明阅读完此邮件后将其删除,更多的属性请参考mail.jar的API
inbox.close(true);
}
if (store != null) {
store.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
// 连接到邮件服务器并获得邮件
Properties prop = new Properties();
prop.put("mail.imap.host", IMAPSERVER);
prop.put("mail.imap.auth.plain.disable","true");
Session session = Session.getDefaultInstance(prop, null);
IMAPStore store = (IMAPStore)session.getStore("imap");
store.connect(pop3Server, username, password);
IMAPFolder inbox = (IMAPFolder)store.getDefaultFolder().getFolder("INBOX");
// 设置inbox对象属性为可读写,这样可以控制在读完邮件后直接删除该附件
inbox.open(Folder.READ_WRITE);
Message[] msg = inbox.getMessages();
FetchProfile profile = new FetchProfile();
profile.add(FetchProfile.Item.ENVELOPE);
inbox.fetch(msg, profile);
for (int i = 0; i < msg.length; i++) {
if (msg[i].getSentDate().before(latestReceiveTime)) {
// 标记此邮件的flag标志对象的DELETED位为true,可以在读完邮件后直接删除该附件,具体执行时间是在调用
// inbox.close()方法的时候
msg[i].setFlag(Flags.Flag.DELETED, true);
}
}
if (inbox != null) {
// 参数为true表明阅读完此邮件后将其删除,更多的属性请参考mail.jar的API
inbox.close(true);
}
if (store != null) {
store.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}