MimeMessage.getAllHeaders()在两个不同的项目中返回两个不同的类

时间:2015-03-03 15:30:23

标签: java mime javax.mail smime

我有一个关于邮件和工作的项目没有问题,但我创建了另一个项目,也是关于邮件生成的MimeMessage无法在第一个项目中解析。

我研究了这些类,发现了MimeMessage的头类之间的区别 这两个项目都在使用

的javax.mail.internet.MimeMessage

但我将标题记录为:

Enumeration enumer = originalUserMessage.getAllHeaders();
while(true){
    try{
        Object obj = enumer.nextElement();
        if(obj == null) {
            break;
        }
        LOGGER.info("Header class: "+obj.getClass().getName());
        LOGGER.info("Header super class:" + obj.getClass().getSuperclass().getName());
    } catch (NoSuchElementException nsee) {
        break;
    }

}

打印的第一个项目:

2015-03-03 16:57:16 INFO  SmimeWriter:204 - Header class: 
javax.mail.Header
2015-03-03 16:57:16 INFO  SmimeWriter:205 - Header super class: 
java.lang.Object

打印第二个项目

2015-03-03 16:57:39 INFO  SmimeWriter:204 - Header class: 
javax.mail.internet.InternetHeaders$InternetHeader
2015-03-03 16:57:39 INFO  SmimeWriter:205 - Header super class: 
javax.mail.Header

所有相关的类似乎都在mail.jar中。我正在使用maven来获取罐子,并且两个项目都得到了那个罐子:

<dependency>
  <groupId>javax.mail</groupId>
  <artifactId>mail</artifactId>
  <version>1.4.2</version>
</dependency>

可能是什么问题。还有其他依赖的罐子吗?

两个项目都使用相同的方法。在下面的代码块之后设置了mime消息的其他部分,但是这里出现问题。 代码:

        MimeMessage originalUserMessage = new MimeMessage(session);

        originalUserMessage.setFrom(from);
        originalUserMessage.setRecipients(Message.RecipientType.TO, to);
        if(cc != null && cc.length>0){
            originalUserMessage.setRecipients(Message.RecipientType.CC, cc);
        }

        Enumeration enumer = originalUserMessage.getAllHeaders();
        while(true){
            try{
                Object obj = enumer.nextElement();
                if(obj == null) {
                    break;
                }
                LOGGER.info("Header class: "+obj.getClass().getName());
                LOGGER.info("Header super class: "+obj.getClass().getSuperclass().getName());
            } catch (NoSuchElementException nsee) {
                break;
            }

        }

1 个答案:

答案 0 :(得分:1)

这根本不是问题。 contract of the MimeMessage.getAllHeaders() method很清楚:

  

将此Message中的所有标题作为Header对象的枚举返回。

该文档指的是javax.mail.Header类。

因此,当您调用MimeMessage.getAllHeaders()时,可以安全地假设Enumeration将返回javax.mail.Header的实例。 可能会或可能不会返回作为Header子类的对象,根据多态的基本规则,这是一个完全有效的事情,只要调用代码可以像Header一样安全地处理它们实例

根据您运行程序的方式,pom.xml中的JavaMail版本可能无关紧要。在Java EE容器(如GlassFish和JBoss)和servlet容器(如Tomcat)中,JavaMail由容器提供,因此即使您将自己的JavaMail版本与应用程序打包在一起,ClassLoader也可以忽略它并无条件地使用提供的JavaMail由服务器环境。

旁注:循环枚举的正确方法是使用hasMoreElements()方法:

while (enumer.hasMoreElements()) {
    Header header = (Header) enumer.nextElement();
    System.out.printf("%s: %s%n", header.getName(), header.getValue());
}

即使使用try / catch技术工作,使用try / catch检测枚举结束也是不正确的。它更慢,更难阅读,并且可能无意中捕获编程错误,这使得调试变得更加困难。