我正在开发一个需要通过JavaMail发送带有特定消息ID的电子邮件的应用程序。
我扩展了Java MimeMessage类以覆盖updateMessageID方法,以便我自己设置消息ID。问题是,当我调用Transport.send(msg)方法时,它没有调用updateMessageID方法。我认为也许我需要在调用Transport.send(msg)之前先调用saveChanges()方法。即使当我显式调用msg.saveChanges()时,这也不会触发调用updateMessageID方法。
令我更加古怪的是,当我将测试应用程序转换为JSP并运行它时,Transport.send(msg)方法确实调用了updateMessageID方法。
我测试过的服务器和Web服务器都在运行jdk1.7.0_71。
扩展的MimeMessage类
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++;
}
}
我从名为SimpleEmail的邮件包装器中将此MimeMessageClass称为。它主要是一堆get / set函数。所有的肉都在sendEmail方法中...
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;
}
因此,当我从JSP调用时,可以看到MyMimeMessage类的两个打印语句
<%@ 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>
在我的日志中,我看到:
Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser@localhost
当我检查生成的电子邮件时,标题中的Message-ID与设置的匹配。
这是我的问题所在,当我运行独立版本时,它仍会发送电子邮件,但不会调用updateMessageID方法,并且不会打印出调试语句。
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!");
}
}
运行此命令时,我得到的唯一输出是:
Done!
而我期待
Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser@localhost
Done!
我整个团队(包括sysadmin)都在这个问题上陷入困境。任何和所有建议将不胜感激!
最佳答案
听起来您要在两个不同的服务器上进行测试,所以我猜测它们正在使用不同版本的JavaMail。他们使用什么版本? JavaMail debug output显示什么?