用javamail接收没有经过编码(转码)的中文附件时,出现javamail javax.mail.internet.ParseException异常

Fandian 2013-06-23 11:12:45
我们查看一封邮件的“原始信息”时(在FOXMAIL,OUTLOOK,或者WEB免费信箱中,都可以查看邮件原始信息,其实就是一个eml格式的文本文件),

在邮件原始信息中,除了可以看到很多有用邮件头信息(From,To,Subject,Content-Type,Message-Id,,,,等等),也可以看到经过编码的邮件内容(包括正文与附件或内嵌资源)

比如带中文名附件的邮件原始信息中的附件应该是以下这样子的,这是一个WORD格式的附件:
Content-Type: application/msword; 
name="=?gb2312?B?azNtbGhxZ3DI57rOvPK7r8rkyOvW2Li00NTUtLXEzsTX1m1lYTk5ZGYuZG9j?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="=?gb2312?B?azNtbGhxZ3DI57rOvPK7r8rkyOvW2Li00NTUtLXEzsTX1m1lYTk5ZGYuZG9j?="


即一个附件包括三个信息:
1,Content-Type
2,Content-Transfer-Encoding
3,Content-Disposition

其中Content-Type有个name属性,Content-Disposition有个filename属性,这其实就是附件的文件名。
它们的值是由三个部分组成的,每个部分用"?"分割:
第一部分:?gb2312?,表示附件文件名是用中文的gb2312字集,即表示有带中文。
第二部分:?B?,表示文件名采用 base64编码。
第三部分:?azNtbGhxZ3DI57rOvPK7r8rkyOvW2Li00NTUtLXEzsTX1m1lYTk5ZGYuZG9j?,这表示经过 base64编码的文件名。


以上说的都是正常情况,此情况下用javamail 接收邮件,完全正常,不会发生任何异常。

但是如果邮件原始信息是以下这样子呢,会发生什么呢?

Content-Type: application/msword;
name=如何lz有效调整薪酬.doc
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename=如何lz有效调整薪酬.doc


上面的邮件,使用javamail的BodyPart.getDisposition(),或BodyPart.getFileName()时,就会发生javamail javax.mail.internet.ParseException:Expected parameter value got "????"异常。

当然,以上两个方法我们在做javamail接收邮件时,必须用到,它们是用于判断邮件是否带附件,以及取得附件的文件名的必须用到的方法。


#####################侵害线######################


以上是异常事件的描述,各位,问题来了。
1,为什么会发生中文名的附件没有转码情况?
2,有什么办法解析此类邮件,能正常取得附件?






...全文
2686 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
iaiti 2013-06-25
  • 打赏
  • 举报
回复
引用 14 楼 Fandian 的回复:
[quote=引用 12 楼 iaiti 的回复:] [quote=引用 10 楼 Fandian 的回复:] [quote=引用 8 楼 iaiti 的回复:] [quote=引用 7 楼 Fandian 的回复:] 有人处理过类似的问题吗?
lz,filename为什么异常,乱码了嘛,你自己能不能把乱码转成正常的,那就正常了。[/quote] 取不出来,不是取出来后乱码。[/quote] 不好意思,是我看错了。楼主,看一下,http://bbs.csdn.net/topics/20060460和你同样问题的。 [/quote] 1,这文章看过,我分析一下。
attachment="d:\网络地址.txt";
mbp2.setFileName(attachment);如果是这样就不能在信箱里正确显示!
如果有人这样发邮件,这肯定是不行的,文件名必须encode才可以;当然我们没办法控制别人发邮件的代码,其实用客户端发是不会这样的,此种情况经常发生在用JAVAMAIL发邮件的,比如注册激活邮件之类的邮件中。 2,这文章里的二楼方法不行,就是我上面说的问题,BodyPart.getFilename()都发生异常了,就不用去谈对它的结果进行处理了,没结果,呵。 [/quote] 那帮不了你了,我不懂。。
Fandian 2013-06-24
  • 打赏
  • 举报
回复
引用 12 楼 iaiti 的回复:
[quote=引用 10 楼 Fandian 的回复:] [quote=引用 8 楼 iaiti 的回复:] [quote=引用 7 楼 Fandian 的回复:] 有人处理过类似的问题吗?
lz,filename为什么异常,乱码了嘛,你自己能不能把乱码转成正常的,那就正常了。[/quote] 取不出来,不是取出来后乱码。[/quote] 不好意思,是我看错了。楼主,看一下,http://bbs.csdn.net/topics/20060460和你同样问题的。 [/quote] 1,这文章看过,我分析一下。
attachment="d:\网络地址.txt";
mbp2.setFileName(attachment);如果是这样就不能在信箱里正确显示!
如果有人这样发邮件,这肯定是不行的,文件名必须encode才可以;当然我们没办法控制别人发邮件的代码,其实用客户端发是不会这样的,此种情况经常发生在用JAVAMAIL发邮件的,比如注册激活邮件之类的邮件中。 2,这文章里的二楼方法不行,就是我上面说的问题,BodyPart.getFilename()都发生异常了,就不用去谈对它的结果进行处理了,没结果,呵。
Fandian 2013-06-24
  • 打赏
  • 举报
回复
有人处理过类似的问题吗?
iaiti 2013-06-24
  • 打赏
  • 举报
回复
异常还是看一下别人的代码吧,那个地方写错了,因为别人只是乱码问题。我刚开始也看错了。
iaiti 2013-06-24
  • 打赏
  • 举报
回复
引用 10 楼 Fandian 的回复:
[quote=引用 8 楼 iaiti 的回复:] [quote=引用 7 楼 Fandian 的回复:] 有人处理过类似的问题吗?
lz,filename为什么异常,乱码了嘛,你自己能不能把乱码转成正常的,那就正常了。[/quote] 取不出来,不是取出来后乱码。[/quote] 不好意思,是我看错了。楼主,看一下,http://bbs.csdn.net/topics/20060460和你同样问题的。
Fandian 2013-06-24
  • 打赏
  • 举报
回复
引用 9 楼 iaiti 的回复:
就像你平时做错东西一样,有时候错了就是错了,要怎么改才最重要!
其实有两种办法,但比较别扭: 1,改写javamail API中的相关类,让它可以取得没有转码的中文文件名。 2,出现异常时,做一下异常处理,然后用另外的方法(不是javamail的)来提取附件。
Fandian 2013-06-24
  • 打赏
  • 举报
回复
引用 8 楼 iaiti 的回复:
[quote=引用 7 楼 Fandian 的回复:] 有人处理过类似的问题吗?
lz,filename为什么异常,乱码了嘛,你自己能不能把乱码转成正常的,那就正常了。[/quote] 取不出来,不是取出来后乱码。
iaiti 2013-06-24
  • 打赏
  • 举报
回复
就像你平时做错东西一样,有时候错了就是错了,要怎么改才最重要!
iaiti 2013-06-24
  • 打赏
  • 举报
回复
引用 7 楼 Fandian 的回复:
有人处理过类似的问题吗?
lz,filename为什么异常,乱码了嘛,你自己能不能把乱码转成正常的,那就正常了。
Fandian 2013-06-23
  • 打赏
  • 举报
回复
引用 5 楼 iaiti 的回复:
自己完善商城的时候遇到过这种问题,附件名其实是文件名,文件名本身读取的时候已经出现乱码,这跟数据库存储出现乱码一样,filename.getBytes("ISO-8859-1"),"gb2312"),先转为正常的字符,本身整个协议本身的转码没错。
呵,首先你要先得到文件名(你上面的filename),才可能去做filename.getBytes("ISO-8859-1"),"gb2312") 但是getFileName()就出异常了,如何得到文件名?!
iaiti 2013-06-23
  • 打赏
  • 举报
回复
自己完善商城的时候遇到过这种问题,附件名其实是文件名,文件名本身读取的时候已经出现乱码,这跟数据库存储出现乱码一样,filename.getBytes("ISO-8859-1"),"gb2312"),先转为正常的字符,本身整个协议本身的转码没错。
caofeng891102 2013-06-23
  • 打赏
  • 举报
回复
学习。
Fandian 2013-06-23
  • 打赏
  • 举报
回复
有人来讨论讨论吗 是否可以通过改写javamail的getFileName(),getDisposition()方法来解决?
Fandian 2013-06-23
  • 打赏
  • 举报
回复
再补充:
从上面截图可以看出,getFileName()其实不会返回"如何lz有效调整薪酬.doc",而是很长很长的乱码。因为去getFileName()的时间,看到的,不是"如何lz有效调整薪酬.doc"中文名,而是乱码。
如下图:


Fandian 2013-06-23
  • 打赏
  • 举报
回复
补充一张异常截图。
javaMail的详细文档,都有以下多有类的详细信息: ACL Address AddressException AddressStringTerm AddressTerm AndTerm AuthenticationFailedException Authenticator BodyPart BodyTerm ByteArrayDataSource ComparisonTerm ConnectionAdapter ConnectionEvent ConnectionListener ContentDisposition ContentType DateTerm DeliveryStatus DispositionNotification FetchProfile FetchProfile.Item Flags Flags.Flag FlagTerm Folder FolderAdapter FolderClosedException FolderEvent FolderListener FolderNotFoundException FromStringTerm FromTerm Header HeaderTerm HeaderTokenizer HeaderTokenizer.Token IllegalWriteException IMAPFolder IMAPFolder.FetchProfileItem IMAPFolder.ProtocolCommand IMAPMessage IMAPSSLStore IMAPStore IntegerComparisonTerm InternetAddress InternetHeaders InternetHeaders.InternetHeader MailDateFormat MailEvent MailHandler MailSSLSocketFactory Message Message.RecipientType MessageAware MessageChangedEvent MessageChangedListener MessageContext MessageCountAdapter MessageCountEvent MessageCountListener MessageHeaders MessageIDTerm MessageNumberTerm MessageRemovedException MessagingException MethodNotSupportedException MimeBodyPart MimeMessage MimeMessage.RecipientType MimeMultipart MimePart MimePartDataSource MimeUtility Multipart MultipartDataSource MultipartReport NewsAddress NoSuchProviderException NotTerm OrTerm ParameterList ParseException Part PasswordAuthentication POP3Folder POP3Message POP3SSLStore POP3Store PreencodedMimeBodyPart Provider Provider.Type Quota Quota.Resource QuotaAwareStore ReadOnlyFolderException ReceivedDateTerm RecipientStringTerm RecipientTerm Report Rights Rights.Right SearchException SearchTerm SendFailedException SentDateTerm Service Session SharedByteArrayInputStream SharedFileInputStream SharedInputStream SizeTerm SMTPAddressFailedException SMTPAddressSucceededException SMTPMessage SMTPSendFailedException SMTPSSLTransport SMTPTransport Store StoreClosedException StoreEvent StoreListener StringTerm SubjectTerm Transport TransportAdapter TransportEvent TransportListener UIDFolder UIDFolder.FetchProfileItem URLName

81,122

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧