我一直在尝试序列化MimeMessage实例,但正如我在网上看到的那样,这是不可能的。我希望通过序列化MimeMessage实例来实现的是我想要散列该实例并将其发送到邮件本身。到目前为止我编码的是:
MimeMessage message = new MimeMessage(session);
//...setting up content of MimeMessage
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("object.ser")));
oos.writeObject(message);
oos.close();
它在GlassFish服务器上编译,但是当我尝试使用服务时出现运行时错误。它说:
exception
java.io.NotSerializableException: javax.mail.internet.MimeMessage
我试着这样做;然而它也没有用:
Object obj = new Object();
obj = (Object)message;
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("object.ser")));
oos.writeObject(obj);
oos.close();
有没有办法实现序列化MimeMessage实例或以其他方式破解它?
答案 0 :(得分:8)
实际上,MimeMessage
does not implement Serializable
by design,你可以扩展MimeMessage
这样做,但你不需要因为MimeMessage
设施使用writeTo(OutputStream)来允许你将内容保存为n RFC-822 mime消息。
try (OutputStream str = Files.newOutputStream(Paths.get("message.eml"))) {
msg.writeTo(str);
}
然后,您可以阅读此消息,以便稍后使用MimeMessage(Session,InputStream)构造函数和会话对象进行处理。
Session session = Session.getInstance(props);
try (InputStream str = Files.newInputStream(Paths.get("message.eml"))) {
MimeMessage msg = new MimeMessage(session, str);
// Do something with the message, maybe send it.
Transport.send(msg);
}
如果您正在使用spring JavaMailSender,那么您还可以使用createMimeMessage(InputStream)使用配置的会话,通过配置的会话构建新的mime消息。
答案 1 :(得分:1)
NotSerializableException
接口时,抛出 java.io.Serializable
。由于javax.mail.internet.MimeMessage未实现此接口,因此无法序列化。
public class MimeMessage extends Message implements MimePart
考虑序列化其内容;通过将其包装在实现Serializable 的自定义域对象(带有消息文本和收件人)中。在需要时反序列化此域对象,然后继续从其内容构造新的 MimeMessage 。
答案 2 :(得分:0)
如其他答案中所述:如果您不需要MimeMessage中的会话信息,则可以使用MimeMessage.writeTo
方法将其存储在可序列化的包装器对象中。作为模板,请参阅以下代码(注意,它不是Null-safe)。
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import com.sun.mail.smtp.SMTPOutputStream;
public class SerializableMimeMessage implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3763328805281033284L;
private transient MimeMessage mimeMessage;
public SerializableMimeMessage(MimeMessage mimeMessage) {
this.mimeMessage = mimeMessage;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
// convert
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SMTPOutputStream os = new SMTPOutputStream(baos);
try {
mimeMessage.writeTo(os);
} catch (MessagingException e) {
throw new IOException("MimeMessage could not be serialized.", e);
}
os.flush();
byte[] serializedEmail = baos.toByteArray();
// default serialization
oos.defaultWriteObject();
// write the object
oos.writeInt(serializedEmail.length);
oos.write(serializedEmail);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
// default deserialization
ois.defaultReadObject();
// read the object
int len = ois.readInt();
byte[] serializedEmail = new byte[len];
ois.readFully(serializedEmail);
// convert
ByteArrayInputStream bais = new ByteArrayInputStream(serializedEmail);
try {
mimeMessage = new MimeMessage((Session) null, bais);
} catch (MessagingException e) {
throw new IOException("MimeMessage could not be deserialized.", e);
}
}
public MimeMessage getMimeMessage() {
return mimeMessage;
}
答案 3 :(得分:0)
这对我有用
序列化
var mailMessage = new MimeMessage();
mailMessage.From.Add(new MailboxAddress("from", "email@example.com"));
mailMessage.To.Add(new MailboxAddress("to", "email2@example.com"));
mailMessage.ReplyTo.Add(new MailboxAddress("reply", "email3@example.com"));
mailMessage.Subject = "Test subject";
var bodyBuilder = new BodyBuilder();
bodyBuilder.TextBody = "GenericEmail";
bodyBuilder.HtmlBody = JsonConvert.SerializeObject(new Settings() { Exchange = "x" });
mailMessage.Body = bodyBuilder.ToMessageBody();
using var memoryStream = new MemoryStream();
mailMessage.WriteTo(memoryStream);
return memoryStream.ToArray();
反序列化
using var stream = new MemoryStream(data);
return MimeMessage.Load(stream);
请注意,我的用例是将电子邮件发送到 AMQP 队列,以便电子邮件发件人在可用或准备就绪时发送它。我的 AMQP 接收器处理电子邮件模板,因此我在文本正文中发送模板,在 htmlbody 中发送变量>