Eu tenho tentado serializar uma instância MimeMessage, mas como eu li na web, não é possível. O que eu quero alcançar com a serialização de uma instância MimeMessage é que eu quero hash essa instância e enviá-lo ao longo do correio em si. O que eu codifiquei até agora é isto:
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();
Ele compila no servidor GlassFish, mas recebo um erro de execução quando tento usar o serviço. Diz:
exception java.io.NotSerializableException: javax.mail.internet.MimeMessage
Eu tentei fazer assim; mas também não funcionou:
Object obj = new Object(); obj = (Object)message; ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("object.ser"))); oos.writeObject(obj); oos.close();
Existe alguma maneira de conseguir a serialização de uma instância do MimeMessage ou de ir ao redor e hackeá-lo de alguma outra forma?
Na verdade, MimeMessage
não implementa Serializable
por design , você pode estender MimeMessage
para fazer isso, mas você não precisa como MimeMessage
tem instalações usando writeTo (OutputStream) para permitir que você salve o conteúdo como n m mensagem RFC-822.
try (OutputStream str = Files.newOutputStream(Paths.get("message.eml"))) { msg.writeTo(str); }
Você pode então ler essa mensagem para processamento posterior usando o construtor MimeMessage (Session, InputStream) com o object de session.
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); }
Se acontecer de você estar usando JavaMailSender da primavera, então você também pode construir novas mensagens mime através da session configurada usando createMimeMessage (InputStream), que usa a session configurada.
NotSerializableException
é lançado quando o object que está sendo serializado não implementa a interface java.io.Serializable
. Como javax.mail.internet.MimeMessage não implementa essa interface, ela não pode ser serializada.
public class MimeMessage extends Message implements MimePart
Considere a serialização de seu conteúdo; agrupando-o em um object de domínio personalizado (com o texto e os destinatários da mensagem) que implementa Serializable . Desselecione este object de domínio quando necessário e, em seguida, vá em frente para construir um novo MimeMessage a partir de seu conteúdo.
Como afirmado em outras respostas: se você não precisa das informações da session no MimeMessage, você pode usar o método MimeMessage.writeTo
para armazená-lo em um object wrapper serializável. Como modelo, veja o código a seguir (Cuidado, não é seguro para nulo).
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; }