java 接收邮件附件乱码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 接收邮件附件乱码相关的知识,希望对你有一定的参考价值。

我在接收邮箱的时候主题和内容都可以转换成中文
唯独就是附件不行
在网上试过N种方法都不行 结果还是乱码
请指教!!

imeUtility.encodeWord是进行编码,MimeUtility.encodeWord是进行解码
无论附件中文件是什么样的字符,都可以进行正确的解码,但是当文件都是英文
文字的时候却会包错,为null,英文这个时候不支持全英文,所以这个时候应该:
if(!part_FileName.endsWith("?=")) //是全英文

直接赋值

else

MimeUtility.decodeWord(文件名字);

messageBodyPart.setFileName(MimeUtility.encodeWord(fileName));
同样收中文附件时,以MimeUtility.decodeWord()将编码后的字符串解码。

字符编码及字符集转换问题
前面提到MIME要解决的另外一个问题就是将SMTP协议不支持的字节流转换成
为SMTP 协议支持的字节流。比如我们要通过邮件传输一个附件文档,该附件文档就
是一个8bit 字节流,如果简单的直接通过SMTP 发送,其最高位信息将被丢失。MIME
规定可以用两种编码方式将8bit 的字节流编码成为低于8bit 的字节流,它们分别是
BASE64 编码(BASE64 将8bit 字节流编码成6bit 字节流)和QP 编码。这两种编码
方式同样应用在对中文的编码上。例如如果邮件中文题目叫做“CVS 介绍”,那么其
编码后的形式可能为:
Subject: =?gb2312?B?Q1ZTLS3QpMX0LnBwdA==?=
标题字符串以”=?”开始,以”?=”结束。”gb2312”表示字符串的字符集,而以”?”分
隔的”B”就表示此字符串的编码方式为BASE64。我们处理此标题时就要先将BASE64
编码的6bit 字节流转换为原来的8bit 字节流,再根据字符集”gb2312”转换为Java 中的
String 类型。这里可以简单的使用JavaMail 提供的MimeUtility.decodeWord()静态方法
将编码后的字符串解码。

文章出处:http://www.diybl.com/course/3_program/java/javashl/20071118/86782.html
参考技术A 可能附件的格式手机不支持,TXT格式可以下一个moto-txt阅读器,doc也可以下一个java阅读器,手机可以看到邮件的正文和标题,附件还是建议用电脑看,或者让发送者把附件内容复制一遍到正文,在或者换一个智能手机便可轻松解决此问题 参考技术B //接受
String attachmentFile = "XXXXXXXX";
//u can get correct attachment filename with this method ^&^
attachmentFile = MimeUtility.decodeText(attachmentFile);

//发邮件的时候这样设置附件名
attachmentPart.setFileName(MimeUtility.encodeText(fds.getName()));

Java 接收附件邮件错误

【中文标题】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邮件开发:解决附件名为乱码及显示友好名称

邮件附件乱码问题

当wireshark抓取到带有附件为乱码的邮件,为看到完整邮件内容

我用jmail发邮件附件 可是收到的都是乱码 怎么办啊?

Django 邮件推送 解决附件中文名字乱码

Java 发送邮件是出现乱码 乱码结果如下: