Enviar un correo electrónico con archivos adjuntos por JavaMailSender de SpringFramework

Este es un breve artículo sobre "cómo hacerlo" sobre el envío de correos electrónicos con SpringFramework. Proporcionaré un par de ejemplos y mostraré un problema popular .

Es una tarea fácil que podría implementarse así:

public void send(String subject, String from, String to, File file) throws MessagingException { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setSubject(subject); helper.setFrom(from); helper.setTo(to); helper.setReplyTo(from); helper.setText("stub", false); helper.addAttachment("document.txt", file); javaMailSender.send(message); } 

Pero no es una situación típica cuando la aplicación web trabaja directamente con el sistema de archivos. Consideremos el ejemplo cuando creamos el documento en la memoria y queremos adjuntarlo a nuestro correo electrónico.

Hay un par de métodos en la clase MimeMessageHelper que podrían ayudarnos:

 public class MimeMessageHelper { ... public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource) { ... } public void addAttachment(String attachmentFilename, DataSource dataSource) throws MessagingException { ... } } 

Veamos algunos ejemplos.

1. El archivo adjunto es una interfaz InputStreamSource

Es complicado, porque en ese caso el desarrollador podría obtener una IllegalArgumentException con un mensaje:

"El recurso aprobado contiene un flujo abierto: argumento no válido. JavaMail requiere un InputStreamSource que crea un flujo nuevo para cada llamada " .

Ocurre porque hay una verificación especial en el método MimeMessageHelper # addAttachment () :

 if (inputStreamSource instanceof Resource && ((Resource) inputStreamSource).isOpen()) { throw new IllegalArgumentException( "Passed-in Resource contains an open stream: invalid argument. " + "JavaMail requires an InputStreamSource that creates a fresh stream for every call."); } 

Por ejemplo, la implementación InputStreamResource siempre devuelve true desde el método isOpen () que hace imposible usar esta implementación como un archivo adjunto:

  public class InputStreamResource extends AbstractResource { //... @Override public boolean isOpen() { return true; } //... } 

El ejemplo de trabajo es:

 public void send() { try { final ByteArrayOutputStream stream = createInMemoryDocument("test document text"); final InputStreamSource attachment = new ByteArrayResource(stream.toByteArray()); sendMimeMessageWithAttachments( "subject", "random@random.com", "random@random.com", attachment); } catch (IOException | MailException | MessagingException e) { logger.warn(e.getMessage(), e); } } private void sendMimeMessageWithAttachments(String subject, String from, String to, InputStreamSource source) throws MessagingException { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setSubject(subject); helper.setFrom(from); helper.setTo(to); helper.setReplyTo(from); helper.setText("stub", false); helper.addAttachment("document.txt", source); javaMailSender.send(message); } private ByteArrayOutputStream createInMemoryDocument(String documentBody) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); outputStream.write(documentBody.getBytes()); return outputStream; } 

2. El archivo adjunto es una interfaz DataSource

Este ejemplo no contiene trampas y es bastante claro:

 public void send() { try { final ByteArrayOutputStream document = createInMemoryDocument("test document text"); final InputStream inputStream = new ByteArrayInputStream(document.toByteArray()); final DataSource attachment = new ByteArrayDataSource(inputStream, "application/octet-stream"); sendMimeMessageWithAttachments( "subject", "anonymous@xyz-mail.com", "anonymous@xyz-mail.com", attachment); } catch (IOException | MailException | MessagingException e) { logger.warn(e.getMessage(), e); } } private void sendMimeMessageWithAttachments(String subject, String from, String to, DataSource dataSource) throws MessagingException { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setSubject(subject); helper.setFrom(from); helper.setTo(to); helper.setReplyTo(from); helper.setText("stub", false); helper.addAttachment("document.txt", dataSource); javaMailSender.send(message); } 

Sería útil echar un vistazo al capítulo de referencia de primavera .

Source: https://habr.com/ru/post/439176/


All Articles