简体   繁体   English

如何序列化 Mimemessage 实例?

[英]How to serialize a Mimemessage instance?

I have been trying to serialize a MimeMessage instance, but as I read on web it is not possible.我一直在尝试序列化 MimeMessage 实例,但正如我在网上阅读的那样,这是不可能的。 What I want to achieve with serializing a MimeMessage instance is that I want to hash that instance and send it along mail itself.我想通过序列化 MimeMessage 实例来实现的是我想对该实例进行哈希处理并将其与邮件本身一起发送。 What I coded so far is this:到目前为止我编码的是这样的:

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();

It compiles on GlassFish server, but I get a runtime error when I try to use service.它在 GlassFish 服务器上编译,但是当我尝试使用服务时出现运行时错误。 It says:它说:

exception

java.io.NotSerializableException: javax.mail.internet.MimeMessage

I tried it to do in this way;我试过这样做; yet it didn't work, either:但它也没有工作:

Object obj = new Object();
obj = (Object)message;
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("object.ser")));
oos.writeObject(obj);
oos.close();

Is there any way to achieve serializing a MimeMessage instance or to go around and hack it in some other way?有没有办法实现序列化 MimeMessage 实例或以其他方式绕过并破解它?

Actually, MimeMessage does not implement Serializable by design , you can extend MimeMessage to do so but you do not need to as MimeMessage has facilities using writeTo(OutputStream) to allow you to save the content as n RFC-822 mime message.实际上, MimeMessage 并没有按设计实现可Serializable ,您可以扩展MimeMessage来实现这一点,但您不需要这样做,因为MimeMessage具有使用writeTo(OutputStream) 的设施,允许您将内容保存为 n RFC-822 mime 消息。

try (OutputStream str = Files.newOutputStream(Paths.get("message.eml"))) {
    msg.writeTo(str);
}

You can then read this message in for later processing using the MimeMessage(Session,InputStream) constructor with the session object.然后,您可以使用带有会话对象的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);
}

If you happen to be using spring's JavaMailSender then you can also construct new mime messages through the configured session by using createMimeMessage(InputStream) which uses the configured session.如果您碰巧使用 spring 的JavaMailSender,那么您还可以使用使用配置会话的createMimeMessage(InputStream)通过配置会话构建新的 MIME 消息。

NotSerializableException is thrown when the Object being serialized does not implement java.io.Serializable interface.当被序列化的 Object 没有实现java.io.Serializable接口时抛出NotSerializableException Since, javax.mail.internet.MimeMessage does not implement this interface it cannot be serialized.由于javax.mail.internet.MimeMessage没有实现这个接口,所以它不能被序列化。

public class MimeMessage extends Message implements MimePart

Consider serializing its content instead;考虑将其内容序列化; by wrapping it up in a custom domain object (with the message text and recipients) that implements Serializable .通过将其包装在实现 Serializable的自定义域对象(带有消息文本和收件人)中。 De-serialize this domain object when required and then go on to construct a new MimeMessage from its contents.在需要时反序列化这个域对象,然后继续从其内容构造一个新的MimeMessage

As stated in other answers: if you don't need the session information in the MimeMessage you can make use of the MimeMessage.writeTo method to store it in a serializable wrapper object.如其他答案所述:如果您不需要 MimeMessage 中的会话信息,您可以使用MimeMessage.writeTo方法将其存储在可序列化的包装对象中。 As a template see the following code (Beware, it's not Null-safe).作为模板,请参阅以下代码(请注意,它不是 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;
    }

This has worked for me这对我有用

Serialisation序列化

            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();

Deserialisation反序列化

            using var stream = new MemoryStream(data);
            return MimeMessage.Load(stream);

Note that my use case is to send the email to AMQP queue, so that the email sender sends it when available or ready.. My AMQP receiver processes the email template so I send the template in textbody and variables in htmlbody请注意,我的用例是将电子邮件发送到 AMQP 队列,以便电子邮件发件人在可用或准备就绪时发送它。我的 AMQP 接收器处理电子邮件模板,因此我将模板发送到 textbody 和 htmlbody 中的变量

We can create MimeMessage and write it to a ByteArrayOutputStream as below:我们可以创建 MimeMessage 并将其写入 ByteArrayOutputStream,如下所示:

JavaMailSenderImpl sender = new JavaMailSenderImpl();
MimeMessage message = sender.createMimeMessage();
MimeMailMessage mimeMailMessage = new MimeMailMessage(message); 
mimeMailMessage.setTo("To@address.com");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
mimeMailMessage.getMimeMessage().writeTo(bos);
byte[] byteArrayMessage = bos.toByteArray());
bos.close();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在MimeMessage中获取所有的mimepart? - how to get all mimeparts in MimeMessage? 如何创建“离线”Java MimeMessage? - how to create an “offline” Java MimeMessage? 如何反序列化具有动态类型属性的实例 - How to de/serialize an instance with dynamically typed attribute 如何根据对象的实例实例调用函数,如果在线程中调用同一实例,则进行序列化,否则不进行序列化 - how to serialize function depending on what instance of object calls it, if same instance call in a thread then do serialize else not Mule ESB-如何获取MimeMessage而不是MimeBodyPart? - Mule ESB - How to get MimeMessage instead of MimeBodyPart? 将一个 MimeMessage 附加到另一个 MimeMessage - Attach a MimeMessage to another MimeMessage 如何使用Interface实例属性序列化类?得到NotSerializableException - How to serialize a Class with an Interface instance attribute? Got NotSerializableException 如何比较两个MimeMessage.java对象以确保它们是相同的? - How to compare two MimeMessage.java objects to make sure they are the same? 如何修改现有的Java邮件MimeMessage正文部分? - How to modify existing Java mail MimeMessage body parts? 如何从javax.mail.internet.MimeMessage重置收件人列表 - how to reset recipient list from javax.mail.internet.MimeMessage
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM