web-dev-qa-db-fra.com

comment utiliser spring envoyer un email avec pièce jointe utiliser InputStream?

la situation est la suivante:

tout d'abord, nous générons un fichier dans la mémoire, nous pouvons obtenir un objet InputStream, ensuite, l'objet InputStream doit être envoyé en tant que pièce jointe d'un e-mail ... le langage utilisé est Java, nous utilisons Spring pour envoyer des e-mails.

je trouve beaucoup, mais je ne trouve pas comment envoyer une pièce jointe à un courriel, utilisez InputStream ... j'essaie de faire comme ceci:

InputStreamSource iss = null;
                    iss = new InputStreamResource(new FileInputStream("c:\\a.txt"));
MimeMessageHelper message = new MimeMessageHelper(mimeMessage,
                        true, "UTF-8");
message.addAttachment("attachment", iss);

mais nous l'exception:

La ressource transmise contient un flux ouvert: argument non valide. JavaMail nécessite une InputStreamSource qui crée un nouveau flux pour chaque appel.

23
kaka2008

Pour les fichiers générés en mémoire, vous pouvez utiliser ByteArrayResource. Convertissez simplement votre objet InputStream en utilisant IOUtils d’Apache Commons. C'est assez simple:

    helper.addAttachment("attachement",
    new ByteArrayResource(IOUtils.toByteArray(inputStream)));
47
ptr07

Consultez le chapitre de référence sur les sources 24.3 Utilisation de JavaMail MimeMessageHelper

L'exemple est à partir de là, je pense qu'il veut que vous vouliez faire:

JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.Host.com");

MimeMessage message = sender.createMimeMessage();

// use the true flag to indicate you need a multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("[email protected]");

helper.setText("Check out this image!");

// let's attach the infamous windows Sample file (this time copied to c:/)
FileSystemResource file = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addAttachment("CoolImage.jpg", file);

sender.send(message);
5
Ralph

Vous pouvez effectuer une implémentation simple de InputStreamSource et y introduire un nouvel InputStream, comme demandé:

InputStreamSource iss = new InputStreamSource() {
    @Override
    public InputStream getInputStream() throws IOException {
        // provide fresh InputStream
        return new FileInputStream("c:\\a.txt");
    }
}
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
message.addAttachment("attachment", iss);
1
Michal Moravcik

// inlineFileObjectCreated - vous pouvez créer un objet StringBuilder pour un exemple 

ByteArrayDataSource source = new ByteArrayDataSource("file name", "contentType", inlineFileObjectCreated.getBytes() );

                JavaMailSender mailSender = (JavaMailSender) ServicesHome.getService("javaMailSender");
                MimeMessage mimeMessage = mailSender.createMimeMessage();
                MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
                mimeMessageHelper.setTo(toArray);           
                mimeMessageHelper.setSubject("");
                mimeMessageHelper.setText("");
                mimeMessageHelper.addAttachment("filename", source);
                mailSender.send(mimeMessageHelper.getMimeMessage());

///////////////////////////////////////////////////

import javax.activation.DataSource;

    public class ByteArrayDataSource implements DataSource {
        byte[] bytes;
        String contentType;
        String name;

        public ByteArrayDataSource( String name, String contentType, byte[] bytes ) {
          this.name = name;
          this.bytes = bytes;
          this.contentType = contentType;
        }

        public String getContentType() {
          return contentType;
        }

        public InputStream getInputStream() {
          return new ByteArrayInputStream(bytes);
        }

        public String getName() {
          return name;
        }

        public OutputStream getOutputStream() throws IOException {
          throw new FileNotFoundException();
        }
      }
0
Sujith

Les exemples de travail sont:

1) La pièce jointe est une interface InputStreamSource

public void send() throws IOException, MessagingException {
    final ByteArrayOutputStream stream = createInMemoryDocument("body");
    final InputStreamSource attachment = new ByteArrayResource(stream.toByteArray());
    final MimeMessage message = javaMailSender.createMimeMessage();
    final MimeMessageHelper helper = new MimeMessageHelper(message, true);
    helper.setSubject("subject");
    helper.setFrom("[email protected]");
    helper.setTo("[email protected]");
    helper.setReplyTo("[email protected]");
    helper.setText("stub", false);
    helper.addAttachment("document.txt", attachment);
    javaMailSender.send(message);
}

2) La pièce jointe est une interface DataSource

public void send() throws IOException, MessagingException {
        final ByteArrayOutputStream document = createInMemoryDocument("body");
        final InputStream inputStream = new ByteArrayInputStream(document.toByteArray());
        final DataSource attachment = new ByteArrayDataSource(inputStream, "application/octet-stream");
        final MimeMessage message = javaMailSender.createMimeMessage();
        final MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setSubject("subject");
        helper.setFrom("[email protected]");
        helper.setTo("[email protected]");
        helper.setReplyTo("[email protected]");
        helper.setText("stub", false);
        helper.addAttachment("document.txt", attachment);
        javaMailSender.send(message);
    }

L'explication:

La ressource transmise contient un flux ouvert: argument non valide. JavaMail requiert un InputStreamSource qui crée un nouveau flux pour Chaque appel.

Ce message peut apparaître si le développeur utilise une implémentation de InputStreamSource qui renvoie true dans la méthode isOpen().

Il y a une vérification spéciale dans la méthode MimeMessageHelper#addAttacment():

public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource, String contentType) {
    //...
    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.");
    }
    //...
}

InputStreamResource#isOpen() renvoie toujours true qui rend impossible l'utilisation de cette implémentation en tant que pièce jointe:

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