Envie um email com anexos por JavaMailSender da SpringFramework

Este é um pequeno artigo sobre como enviar e-mails com o SpringFramework. Vou fornecer alguns exemplos e mostrarei um problema popular .

É uma tarefa fácil que pode ser implementada assim:

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

Mas não é uma situação típica quando o aplicativo da web trabalha diretamente com o sistema de arquivos. Vamos considerar o exemplo quando criamos o documento na memória e queremos anexá-lo ao nosso email.

Existem alguns métodos na classe MimeMessageHelper que podem nos ajudar:

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

Vamos ver alguns exemplos.

1. O anexo é uma interface InputStreamSource

É complicado, porque nesse caso o desenvolvedor pode obter uma IllegalArgumentException com uma mensagem:

"O recurso transmitido contém um fluxo aberto: argumento inválido. JavaMail requer um InputStreamSource que cria um fluxo fresco para cada chamada. "

Isso acontece porque há uma verificação especial no 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 exemplo, a implementação InputStreamResource sempre retorna true do método isOpen () que torna impossível usar essa implementação como um anexo:

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

O exemplo de trabalho é:

 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. O anexo é uma interface DataSource

Este exemplo não contém armadilhas e é 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); } 

Seria útil dar uma olhada no capítulo de referência da primavera .

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


All Articles