当前位置: 首页 > 知识库问答 >
问题:

Java MimeMessage.SaveChanges未调用updateMessageID

滕学义
2023-03-14

我正在开发一个应用程序,需要通过JavaMail发送带有特定消息ID的电子邮件。

我已经扩展了Java的MimeMessage类来重写updateMessageID方法,这样我就可以自己设置消息ID了。问题是,当我调用transport.send(msg)方法时,它没有调用updateMessageID方法。我想在调用transport.send(msg)之前可能需要调用saveChanges()方法。即使显式调用msg.saveChanges(),这也不会触发要调用的updateMessageID方法。

更奇怪的是,当我将测试应用程序转换为JSP并运行它时,transport.send(msg)方法调用updateMessageID方法。

我测试的服务器和webserver都运行JDK1.7.0_71。

扩展MimeMessage类

null

package com.my.framework;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MYMimeMessage extends MimeMessage {
Session session;
private static int id = 0;
private static String messageID = null;

public MyMimeMessage(Session session) {
    super(session);
    this.session=session;
}

protected void updateMessageID() throws MessagingException {
    System.out.println("Calling updateMessageID()");
    setHeader("Message-ID", "<" + getUniqueMessageIDValue(session) + ">");
}

/* Added to pass message id in */
public static void setMessageID(String cid) 
{
   messageID = cid;
}

public static String getUniqueMessageIDValue(Session ssn) {
    String suffix = null;

    InternetAddress addr = InternetAddress.getLocalAddress(ssn);
    if (addr != null)
        suffix = addr.getAddress();
    else {
        suffix = "javamailuser@localhost"; // worst-case default
    }
	
    if(messageID == null)
    {
      messageID = "987654321";
    }
    StringBuffer s = new StringBuffer();
	
    // Unique string is <messageID>.<id>.<currentTime>.FDDMail.<suffix>
    s.append(messageID).append('.').append(getUniqueId()).append('.').
      append(System.currentTimeMillis()).append('.').
      append("FDDMail.").
      append(suffix);
    System.out.println("RETURNING THE new ID: " + s.toString()");
    return s.toString();
}

private static synchronized int getUniqueId() {
	return id++;
}
}

null

我从一个名为SimpleEmail的邮件包装器将其称为MimeMessageClass。它主要是一堆get/set函数。所有的肉都是用sendEmail方法...

null

public String sendEmail()
{
   String msgText1 = this.getBody();
   // Create some properties and get the default Session
   Properties props = System.getProperties();
   props.put("mail.smtp.host", this.getSmtpClient());
   props.put("mail.from", "");

   Session session = Session.getDefaultInstance(props, null);

   try
   {
      // Create a message
      MyMimeMessage msg = new MyMimeMessage(session);

      if (null != sender && sender.length() > 0)
      {
         msg.setSender(new InternetAddress(sender));
      }

      if((this.getReply_to() != null) && (this.getReply_to().length() > 0))
      {
         Address emailReplyTo[] = new Address[1];
         emailReplyTo[0] = new InternetAddress(this.getReply_to());
         msg.setReplyTo(emailReplyTo);
      }

      msg.setFrom(new InternetAddress(this.getFrom()));

      if(this.to == null || this.to.size() <= 0)
      {
         return "Error: No To to send";
      }

      int toIndex = 0;
      InternetAddress [] address = new InternetAddress [this.to.size()];
      while(this.HasNextTo())
      {
         address[toIndex] = new InternetAddress(this.nextTo());
         toIndex++;
      }

      msg.setRecipients(Message.RecipientType.TO, address);

      if(this.subject == null)
      {
         this.subject = "<no subject>";
      }
      msg.setSubject(this.subject);
      if(!useTextHeader)
      {
         //Create and fill the first message part
         MimeBodyPart mbp1 = new MimeBodyPart();
         mbp1.setDataHandler(new DataHandler(new HTMLDataSource(msgText1)));

         Multipart mp = new MimeMultipart();
         mp.addBodyPart(mbp1);
         // Create the second message part
         MimeBodyPart mbp2;
         FileDataSource fds;
         String filename;
         if(this.attachments != null) {
            Set attachmentPathAndNames = this.attachments.keySet();
            Iterator attachmentIterator = attachmentPathAndNames.iterator();
            while(attachmentIterator.hasNext()) {
               String attachmentPathAndName = (String)attachmentIterator.next();
               filename = (String)this.attachments.get(attachmentPathAndName);
               if(filename == null) {
                  String[] dirs = attachmentPathAndName.split("\\/");
                  filename = dirs[dirs.length - 1];
               }

               mbp2 = new MimeBodyPart();
               fds = new FileDataSource(attachmentPathAndName);
               mbp2.setDataHandler(new DataHandler(fds));
               mbp2.setFileName(filename);
               //Create the Multipart and its parts to it
               mp.addBodyPart(mbp2);
            }
         }

         //add the Multipart to the message
         msg.setContent(mp);
      }
      else
      {
         msg.setText(msgText1);
      }

      //set the Date: header
      msg.setSentDate(new Date());

      //set the MessageID Header
      msg.setMessageID(this.messageID);
      //send the message
      try
      {
         Transport.send(msg);
      }
      catch(Exception e)
      {
         System.out.println("STOP WE THREW AN ERROR!!!!!!!!!!!!!!!");
      }
   }
   catch (MessagingException mex)
   {
      mex.printStackTrace();
      System.out.println("Error: SimpleEmail.SendEmail() = Caught MessagingException: " + mex.toString());
      return "Error: SimpleEmail.SendEmail() = Caught MessagingException: " + mex.toString();
   }
   return this.SUCESS_MESSAGE;
}

null

因此,当我从JSP调用时,可以看到MyMimeMessage类中的两个print语句

null

<%@ page import="com.ifx.framework.SimpleEmail" %>
<%
      String toAddr = request.getParameter("emailAddr");
      String mid = request.getParameter("customID");
      String SMTP_CLIENT = "myserver.mydomain.com";

      String body = "Hi " + toAddr + "!<br>Today we are testing to see if the setting messageID to " + mid + " works!";

      String sendResult = "No Email Sent";
      if(toAddr != null)
      {
         SimpleEmail se = new SimpleEmail();
         se.addTo(toAddr);
         se.setSubject("Testing Headers");
         se.setSmtpClient(SMTP_CLIENT);
         se.setFrom("cms_zippylube@gointranet.com");
         se.setBody(body);
         se.setMessageID(mid);
         sendResult = se.sendEmail();
      }
%>
<!DOCTYPE html>
<html>
   <head>
      <title>
         Test Page
      </title>
      <style>
         label {
            width: 200px;
            display: inline-block;
            margin-bottom: 5px;
         }
      </style>
   </head>
   <body>
      <p style="background-color: #ADD8E6; border: solid 2px #000080;">
         <%=sendResult%>
      </p>
      <form action="#" method="post">
         <label for=emailAddr>Email Address:</label><input id="emailAddr" name="emailAddr" type="email"/> <br>
         <label for=customValue>Custom Message ID:</label><input id="customID" name="customID" type="text"/> <br>
         <input type="submit" value="Submit"/>
      </form>
   </body>
</html>

null

在我的日志中我看到:

Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser@localhost

当我检查生成的电子邮件时,头中的Message-ID与设置的匹配。

这就是我的问题所在,当我运行独立版本时,它仍然发送电子邮件,但不调用updateMessageID方法,也不打印调试语句。

null

import com.ifx.framework.SimpleEmail;

public class headerTest
{
   public static void main(String args[])
   {
      String toAddr = args[0];
      String mid = args[1];
      String SMTP_CLIENT = "myserver.mydomain.com";

      String body = "Hi " + toAddr + "!<br>Today we are testing to see if the header message id is retained";

      String sendResult = "No Email Sent";
      if(toAddr != null)
      {
         SimpleEmail se = new SimpleEmail();
         se.addTo(toAddr);
         se.setSubject("Testing Headers");
         se.setSmtpClient(SMTP_CLIENT);
         se.setFrom("dummy@test.com");
         se.setBody(body);
         se.setMessageID(mid);
         sendResult = se.sendEmail();
      }
      System.out.println("Done!");
   }
}

null

运行时得到的唯一输出是:

Done!

而我却在期待

Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser@localhost
Done!

我的整个团队(包括sysadmin)都在这个问题上被难倒了。任何和所有的建议将非常感谢!

共有1个答案

南宫才艺
2023-03-14

听起来像是在用两个不同的服务器进行测试,所以我猜他们使用的是不同版本的JavaMail。他们在用什么版本?JavaMail调试输出显示了什么?

 类似资料:
  • 我正在开发一个带有ActionBars的应用程序,它支持姜饼和其他功能。所以基本上我在使用支持库并扩展 行动B活动 对于我所有的活动。除了 onSupportNavigateUp() 方法。它只是不被调用在留档中所述。 每当用户选择从操作栏在应用程序的活动层次结构中向上导航时,就会调用此方法。 这很容易,但我一直不明白为什么它不能像预期的那样工作,谷歌也帮不上忙。这是虫子吗?还是我错过了什么?

  • 运行playstore Build Apk时,未调用Marshmallow Runtime Permissions onRequestPermissionsResult,但正常调试Apk时运行良好。谁来帮帮我。。谢谢 OnRequestPermissionResult方法

  • 我很难让正常工作。无论我怎么努力,我都不能让它被称为。 我的应用程序的体系结构如下所示:我的主活动包含一个片段,其中包含一个ViewPager,而ViewPager又有四个子片段实例。目前,我正在(成功地)用填充活动中的初始选项菜单,但我希望添加一些对应于每个活动子片段的额外选项。 如果有人知道这里发生了什么,我会非常感激,因为我已经被困在这个问题上两天了。 更新--我已经搞清楚了现在的问题是什么

  • CustomDialog 下面是http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample

  • 我使用: null 我正在使用zuul和负载平衡rest模板从另一个微服务调用一个微服务: 请求到达下游服务,但未在ZullFilter中设置头(我使用了不同的头): 我还创建了一个过滤器: 我错过了什么?为什么不能调用筛选器?在我的案件中是否应该引用?

  • 我试图发送一个意图,从一个活动中的创建启动一个意图服务。但是,IntentService的onHandleIntent永远不会被接收。我尝试过用意图过滤器改变清单,但似乎没有任何效果。没有抛出异常,但是根本没有调用IntentService。 这是onCreate 这是IntentService类的创建者和OnHandleContent,我知道它不会被调用,因为logcat从不显示“检索到的意图”