Java 接收附件邮件错误

Posted

技术标签:

【中文标题】Java 接收附件邮件错误【英文标题】:Java Receiving attachment mail error 【发布时间】:2012-05-21 17:06:46 【问题描述】:

我有一个使用 java 邮件获取附件的 java 代码,我可以下载附件并插入到特定文件夹中。但问题是当我从黑莓手机发送带有附件的电子邮件时,下载附件时出现如下错误。

ERROR [STDERR] java.io.FileNotFoundException: E:\CCjboss\server\sor
emicc\deploy\eis.ear\CC.war\attachment\=?utf-8?B?MS5qcGc= (The filename, directo
ry name, or volume label syntax is incorrect)
07:31:10,739 ERROR [STDERR]     at java.io.FileOutputStream.open(Native Method)
07:31:10,741 ERROR [STDERR]     at java.io.FileOutputStream.<init>(FileOutputStr
eam.java:179)
07:31:10,744 ERROR [STDERR]     at java.io.FileOutputStream.<init>(FileOutputStr
eam.java:131)
07:31:10,747 ERROR [STDERR]     at com.infosense.eis.webapp.util.Mobilekiran.sav
eFile(Mobilekiran.java:230)
07:31:10,750 ERROR [STDERR]     at com.infosense.eis.webapp.util.Mobilekiran.Mob
ileTimeCheckTask(Mobilekiran.java:179)
07:31:10,753 ERROR [STDERR]     at com.infosense.eis.webapp.util.Mobilekiran.run
(Mobilekiran.java:38)
07:31:10,756 ERROR [STDERR]     at java.util.TimerThread.mainLoop(Timer.java:432
)
07:31:10,759 ERROR [STDERR]     at java.util.TimerThread.run(Timer.java:382)

我认为它存在一些编码和解码问题。附件被编码或其他东西

=?utf-8?B?MS5qcGc=

以下是接收带有附件的电子邮件的代码

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
import java.io.*;
import java.util.*;
import java.lang.String;
import javax.mail.internet.*;
/**
 *
 * @author  Administrator
 */
public class Mobilekiran extends TimerTask
     List emattach=new ArrayList();
  List emails = new ArrayList();
  List attachments=new ArrayList();
  String emailbody=null;
  String bodypart=null;
  String s1=null;
  String fromaddress=null;
  String subject=null;
  String body=null;
  String date1=null;
  String filename=null;
  int filesize=0;

    public void run() 
        MobileTimeCheckTask(); 
    

    private void MobileTimeCheckTask()

    String host = "mail.**********.com";
    String username = "*****@****.com";
    String password = "*******";
    String downloadDir = "E:/CCjboss/server/soremicc/deploy/eis.ear/CC.war/attachment";
    String provider = "pop3";
        try

             // Create empty properties
  Properties props = new Properties();

  // Get the session
  Session session = Session.getInstance(props, null);

  // Get the store
  Store store = session.getStore("pop3");
  store.connect(host, username, password);

  // Get folder
  Folder folder = store.getFolder("INBOX");
  folder.open(Folder.READ_WRITE);


  Message messages[] = folder.getMessages();
   for (int i = 0; i < messages.length; i++) 


    // from 
       Address[] toaddress1=messages[i].getAllRecipients();
      String toaddress=toaddress1[0].toString();
       System.out.println("to address"+toaddress1[0].toString());

    emails.add(0,messages[i].getFrom()[0].toString());
    s1=messages[i].getFrom()[0].toString();
    InternetAddress address = new InternetAddress(s1);
     fromaddress=address.getAddress();

    // subject
    emails.add(1,messages[i].getSubject());
    subject=messages[i].getSubject();
    // received date
    if (messages[i].getReceivedDate() != null) 
     emails.add(2,messages[i].getReceivedDate().toString());
     date1=messages[i].getReceivedDate().toString();
      // emattach.add(0,emails);
     else 
     emails.add(2,new Date());
     date1=(new Date()).toString();
      // emattach.add(0,emails);
    

    // body and attachments
    //email.body = "";
    Object content = messages[i].getContent();
    if (content instanceof java.lang.String) 

     emails.add(3,(String) content);

     else if (content instanceof Multipart) 

     Multipart mp = (Multipart) content;
     boolean d=true;
     for (int j = 0; j < mp.getCount(); j++) 

      Part part = mp.getBodyPart(j);
      BodyPart bp=mp.getBodyPart(j);
      Object o2 = bp.getContent();
      if (o2 instanceof String) 

                            System.out.println("**This is a String BodyPart**");
                            System.out.println("bodypart "+(String)o2);
                            if(d)

                            emails.add(3,(String)o2);
                            body=(String)o2;
                            d=false;

                         

      String disposition = part.getDisposition();

      if (disposition == null) 

       MimeBodyPart mbp = (MimeBodyPart) part;
       if (mbp.isMimeType("text/plain")) 
        // Plain

        emailbody += (String) mbp.getContent();
           emails.add(3,emailbody);

        

       else if ((disposition != null) && (disposition.equals(Part.ATTACHMENT) || disposition .equals(Part.INLINE))) 

       // Check if plain
       MimeBodyPart mbp = (MimeBodyPart) part;
       if (mbp.isMimeType("text/plain")) 

           emailbody += (String) mbp.getContent();
           emails.add(3,emailbody);

        else 
        //EmailAttachment attachment = new EmailAttachment();

           System.out.println("the filename  i required"+part.getFileName().toString());


        attachments.add(0,Mobilekiran.decodeName(part.getFileName()));
         filename=decodeName(part.getFileName());
        File savedir = new File(downloadDir);
        savedir.mkdirs();
        // File savefile = File.createTempFile( "emailattach", ".atch", savedir);
        File savefile = new File(downloadDir,attachments.get(0).toString());
        attachments.add(1,savefile.getAbsolutePath());
        attachments.add(2,new Integer(Mobilekiran.saveFile(savefile, part)));
        filesize=saveFile(savefile,part);
        emattach.add(0,attachments);
       
      
      // end of multipart for loop 
    emattach.add(0,emails);
   System.out.println(emattach);
   emattach.clear();
   System.out.println(emattach);
    messages[i].setFlag(Flags.Flag.DELETED , true);

       // end messages for loop



    // Finally delete the message from the server.

   

   // Close connection
   folder.close(true); // true tells the mail server to expunge deleted messages
   store.close();
        catch(Exception e)
            e.printStackTrace();
         
      
    private static String decodeName(String name) throws Exception 
  if (name == null || name.length() == 0) 
   return "unknown";
  
  String ret = java.net.URLDecoder.decode(name, "UTF-8");

  // also check for a few other things in the string:
  ret = ret.replaceAll("=\\?utf-8\\?q\\?", "");
  ret = ret.replaceAll("\\?=", "");
  ret = ret.replaceAll("=20", " ");

  return ret;
 

 private static int saveFile(File saveFile, Part part) throws Exception 

  BufferedOutputStream bos = new BufferedOutputStream(
    new FileOutputStream(saveFile));

  byte[] buff = new byte[2048];
  InputStream is = part.getInputStream();
  int ret = 0, count = 0;
  while ((ret = is.read(buff)) > 0) 
   bos.write(buff, 0, ret);
   count += ret;
  
  bos.close();
  is.close();
  return count;
 

请帮我解决上述问题。

【问题讨论】:

字符串=?utf-8?B?MS5qcGc= 是“1.jpg”的mime / base64 编码版本。我原以为 javamail 在使用 getFileName 时会自动解码。 没有,原因如下:(oracle.com/technetwork/java/javamail/faq/…) 【参考方案1】:

附件似乎已编码。

【讨论】:

对于解码,我们使用 private static String decodeName(String name) throws Exception if (name == null || name.length() == 0) return "unknown"; String ret = java.net.URLDecoder.decode(name, "UTF-8"); // 还要检查字符串中的一些其他内容: ret = ret.replaceAll("=\\?utf-8\\?q\\?", ""); ret = ret.replaceAll("\\?=", ""); ret = ret.replaceAll("=20", " ");返回 ret; 这是 UTF-8 解码。如您的问题中所述,该消息使用公钥编码。如果没有私钥,您将无法阅读它们。据我所知,RIM 在邮寄前会加密所有邮件。同样的原因,RIM 的服务在印度暂停了一段时间。

以上是关于Java 接收附件邮件错误的主要内容,如果未能解决你的问题,请参考以下文章

Java mail发送邮件附件出现.eml文件夹

Mailkit - 接收从苹果邮件发送的消息时没有附件或 html 正文

python实现邮件接收附件下载操作

python实现邮件接收附件下载操作

javaMail邮件接收解析内容及附件 及删除邮件

邮件实现详解------JavaMail 发送(带图片和附件)和接收邮件