javamail定时读取邮箱的未读邮件(imap)

来源:互联网 发布:中国银河证券软件 编辑:程序博客网 时间:2024/04/29 12:40

为啥不用pop3而用imap,是因为imap能把邮件设置为已读,而pop3不能;

使用javamail mail.imap读取邮箱的邮件,综合网上的例子,贴出自己实际使用的代码供大家参考:

步骤: 1、设置被读取邮箱的安全性,允许我们的系统读取邮件,例如:网易邮箱,当读取邮件的时候,网易的邮箱会受到一封标题为网易邮箱提醒:阻止了一次不安全的收信请求“的邮件


第二部:读取邮件和附件,每次读取未读的邮件,读完后,把邮件设为未读,我的这个需求不会考虑人工登录邮箱,读取邮件的情况,如果需要考虑,请略作修改

package com.ch.service.imp;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.util.Date;import java.util.Properties;import javax.annotation.Resource;import javax.mail.Address;import javax.mail.BodyPart;import javax.mail.Flags;import javax.mail.Folder;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Multipart;import javax.mail.Part;import javax.mail.Session;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;import javax.mail.internet.MimeUtility;import org.springframework.stereotype.Service;import com.ch.dao.DocInfoMapper;import com.ch.dao.EmailInfoMapper;import com.ch.entity.DocInfo;import com.ch.entity.EmailInfo;import com.ch.service.MailInfoService;import com.ch.util.Constant;import com.ch.util.RmdeskConfig;import com.ch.util.TypeCastUtil;import com.sun.mail.imap.IMAPFolder;import com.sun.mail.imap.IMAPStore;@Service("mailInfoService")public class MailInfoServiceImpl implements MailInfoService{ @Resource private DocInfoMapper infoMapper; @Resource private EmailInfoMapper emailInfoMapper; @Overridepublic void readMail(){try {Properties prop = System.getProperties();prop.put("mail.store.protocol", RmdeskConfig.mailstoreprotocol);prop.put("mail.imap.host", RmdeskConfig.mailimaphost);Session session = Session.getInstance(prop);IMAPStore store = (IMAPStore) session.getStore(RmdeskConfig.mailstoreprotocol); // 使用imap会话机制,连接服务器store.connect(RmdeskConfig.euser, RmdeskConfig.epassword);IMAPFolder folder = (IMAPFolder) store.getFolder("INBOX"); // 收件箱folder.open(Folder.READ_WRITE);//获取未读邮件Message[] messages = folder.getMessages(folder.getMessageCount()-folder.getUnreadMessageCount()+1,folder.getMessageCount());parseMessage(messages); //解析邮件//释放资源if (folder != null) folder.close(true);if (store != null) store.close();System.out.println("读取成功。。。。。。。。。。。。");} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}          /**      * 解析邮件      * @param messages 要解析的邮件列表      */      private void parseMessage(Message ...messages) throws MessagingException, IOException {          if (messages == null || messages.length < 1)               throw new MessagingException("未找到要解析的邮件!");                    // 解析所有邮件          for (int i = 0, count = messages.length; i < count; i++) {              MimeMessage msg = (MimeMessage) messages[i];              msg.setFlag(Flags.Flag.SEEN, true);              //存储邮件信息            EmailInfo emaininfo = new EmailInfo();            emaininfo.setEmailcode(msg.getMessageID()); //ID            InternetAddress address = getFrom(msg);            emaininfo.setSender(address.getPersonal()+"<" + address.getAddress() + ">");//张三<zhangsan@163.com>            emaininfo.setTitle(decodeText(msg.getSubject()));//转码后的标题            emaininfo.setReceiver(getReceiveAddress(msg, null));//收件人            emaininfo.setAccepttime(msg.getSentDate());//收件日期            emaininfo.setCheckstatus(Constant.CHECK_STATUS_NO);            try {                emailInfoMapper.insert(emaininfo);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();System.out.println("----邮件信息存入数据库失败了。。。。。");}                        if (isContainAttachment(msg)) {//保存附件                  saveAttachment(msg, RmdeskConfig.filepath,address.getAddress(),address.getPersonal());             }         }    }            /**      * 获得邮件发件人      * @param msg 邮件内容     * @return 地址      * @throws MessagingException      * @throws UnsupportedEncodingException       */    private InternetAddress getFrom(MimeMessage msg) throws MessagingException, UnsupportedEncodingException {          Address[] froms = msg.getFrom();          if (froms.length < 1)              throw new MessagingException("没有发件人!");                  return (InternetAddress) froms[0];      }            /**      * 根据收件人类型,获取邮件收件人、抄送和密送地址。如果收件人类型为空,则获得所有的收件人      * <p>Message.RecipientType.TO  收件人</p>      * <p>Message.RecipientType.CC  抄送</p>      * <p>Message.RecipientType.BCC 密送</p>      * @param msg 邮件内容      * @param type 收件人类型      * @return 收件人1 <邮件地址1>, 收件人2 <邮件地址2>, ...      * @throws MessagingException      */      private String getReceiveAddress(MimeMessage msg, Message.RecipientType type) throws MessagingException {          StringBuffer receiveAddress = new StringBuffer();          Address[] addresss = null;          if (type == null) {              addresss = msg.getAllRecipients();          } else {              addresss = msg.getRecipients(type);          }                    if (addresss == null || addresss.length < 1)              throw new MessagingException("没有收件人!");          for (Address address : addresss) {              InternetAddress internetAddress = (InternetAddress)address;              receiveAddress.append(internetAddress.toUnicodeString()).append(",");          }                    receiveAddress.deleteCharAt(receiveAddress.length()-1); //删除最后一个逗号                    return receiveAddress.toString();      }            /**      * 判断邮件中是否包含附件      * @param msg 邮件内容      * @return 邮件中存在附件返回true,不存在返回false      * @throws MessagingException      * @throws IOException      */      private boolean isContainAttachment(Part part) throws MessagingException, IOException {          boolean flag = false;          if (part.isMimeType("multipart/*")) {              MimeMultipart multipart = (MimeMultipart) part.getContent();              int partCount = multipart.getCount();              for (int i = 0; i < partCount; i++) {                  BodyPart bodyPart = multipart.getBodyPart(i);                  String disp = bodyPart.getDisposition();                  if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {                      flag = true;                  } else if (bodyPart.isMimeType("multipart/*")) {                      flag = isContainAttachment(bodyPart);                  } else {                      String contentType = bodyPart.getContentType();                      if (contentType.indexOf("application") != -1) {                          flag = true;                      }                                              if (contentType.indexOf("name") != -1) {                          flag = true;                      }                   }                                    if (flag) break;              }          } else if (part.isMimeType("message/rfc822")) {              flag = isContainAttachment((Part)part.getContent());          }          return flag;      }           /**       * 保存附件       * @param part 邮件中多个组合体中的其中一个组合体       * @param destDir  附件保存目录       * @throws UnsupportedEncodingException       * @throws MessagingException       * @throws FileNotFoundException       * @throws IOException       */      private void saveAttachment(Part part, String destDir,String email,String sendName) throws UnsupportedEncodingException, MessagingException,              FileNotFoundException, IOException {          if (part.isMimeType("multipart/*")) {              Multipart multipart = (Multipart) part.getContent();    //复杂体邮件              //复杂体邮件包含多个邮件体              int partCount = multipart.getCount();              for (int i = 0; i < partCount; i++) {                  //获得复杂体邮件中其中一个邮件体                  BodyPart bodyPart = multipart.getBodyPart(i);                  //某一个邮件体也有可能是由多个邮件体组成的复杂体                  String disp = bodyPart.getDisposition();                  if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {                      InputStream is = bodyPart.getInputStream();                      this.saveFile(is, destDir, decodeText(bodyPart.getFileName()),email,sendName);                  } else if (bodyPart.isMimeType("multipart/*")) {                      saveAttachment(bodyPart,destDir,email,sendName);                  } else {                      String contentType = bodyPart.getContentType();                      if (contentType.indexOf("name") != -1 || contentType.indexOf("application") != -1) {                      this.saveFile(bodyPart.getInputStream(), destDir, decodeText(bodyPart.getFileName()),email,sendName);                      }                  }              }          } else if (part.isMimeType("message/rfc822")) {              saveAttachment((Part) part.getContent(),destDir,email,sendName);          }      }            /**       * 读取输入流中的数据保存至指定目录       * @param is 输入流     * @param fileName 文件名       * @param destDir 文件存储目录       * @throws FileNotFoundException       * @throws IOException       */      private void saveFile(InputStream is, String destDir, String fileName,String email,String sendName)              throws FileNotFoundException, IOException {      //附件格式过滤    if(!TypeCastUtil.equals(RmdeskConfig.extname, TypeCastUtil.getFileDot(fileName))){    return;    }             DocInfo doc = new DocInfo();    doc.setDocName(fileName);    String uuidFilename = TypeCastUtil.getUUIDFileName(fileName);    doc.setUrl(uuidFilename);    doc.setBusinessLine("测试");    doc.setReceivedMode(Constant.OWNER_TYPE_EMAIL);    doc.setReceivedTime(new Date());    doc.setOwnerEmail(email);    doc.setOwnerName(sendName);    //TODO:入库    try {    infoMapper.insert(doc);} catch (Exception e) {e.printStackTrace();System.out.println("----附件存入数据库失败了。。。。。");}            BufferedInputStream bis = new BufferedInputStream(is);          BufferedOutputStream bos = new BufferedOutputStream(                  new FileOutputStream(new File(destDir + uuidFilename)));          int len = -1;          while ((len = bis.read()) != -1) {              bos.write(len);            bos.flush();        }        bos.close();          bis.close();      }            /**      * 文本解码      * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本      * @return 解码后的文本      * @throws UnsupportedEncodingException      */      private String decodeText(String encodeText) throws UnsupportedEncodingException {          if (encodeText == null || "".equals(encodeText)) {              return "";          } else {            return MimeUtility.decodeText(encodeText);          }      }  }


3、定时器以及项目启动时启动定时器


package com.ch.util;import java.util.Timer;import java.util.TimerTask;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import com.ch.service.MailInfoService;public class RmdeskServletContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent arg0) {System.out.println("-------------进入---ServletContextEvent----------------");Timer timer = new Timer();//ApplicationContext context = new ClassPathXmlApplicationContext("classpath:resources/conf/application-*.xml");final MailInfoService service = SpringContextUtil.getBean("mailInfoService");//(MailInfoService)context.getBean("mailInfoService");timer.schedule(new TimerTask() {@Overridepublic void run() {// TODO Auto-generated method stubservice.readMail();}}, 1000,1000*60*60*24);//1000*60*60*24}@Overridepublic void contextDestroyed(ServletContextEvent args) {// TODO Auto-generated method stub}}

web.xml

<listener>          <listener-class>com.ch.util.RmdeskServletContextListener</listener-class>  </listener>


注意:1、如果需要读取文件内容失败,标题可以成功,可以采取以下方式试试:
IMAPMessage imapMessage =(IMAPMessage)message;MimeMessage cmsg = new MimeMessage((MimeMessage) imapMessage); System.out.println("内容:" + cmsg.getContent());


另:摘抄网上的读取文件内容,我自己的项目中用不到,供大家参考

 /**      * 获得邮件文本内容      * @param part 邮件体      * @param content 存储邮件文本内容的字符串      * @throws MessagingException      * @throws IOException      */      public static void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {          //如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断          boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;           if (part.isMimeType("text/*") && !isContainTextAttach) {              content.append(part.getContent().toString());          } else if (part.isMimeType("message/rfc822")) {               getMailTextContent((Part)part.getContent(),content);          } else if (part.isMimeType("multipart/*")) {              Multipart multipart = (Multipart) part.getContent();              int partCount = multipart.getCount();              for (int i = 0; i < partCount; i++) {                  BodyPart bodyPart = multipart.getBodyPart(i);                  getMailTextContent(bodyPart,content);              }          }      }  



暂时就到这里了,有疑问欢迎大家随时沟通!



1 0
原创粉丝点击