如何序列化Mimemessage实例?

时间:2013-07-12 06:50:42

标签: java servlets serialization glassfish mime-message

我一直在尝试序列化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实例或以其他方式破解它?

4 个答案:

答案 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)

当序列化的Object未实现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 中发送变量