【问题标题】:How to attach multiple files to an email using JavaMail?如何使用 JavaMail 将多个文件附加到电子邮件?
【发布时间】:2021-03-20 02:20:40
【问题描述】:

以下 Java 代码用于将文件附加到电子邮件。我想通过电子邮件发送 多个 文件附件。任何建议将不胜感激。

public class SendMail {

    public SendMail() throws MessagingException {
        String host = "smtp.gmail.com";
        String Password = "mnmnn";
        String from = "xyz@gmail.com";
        String toAddress = "abc@gmail.com";
        String filename = "C:/Users/hp/Desktop/Write.txt";
        // Get system properties
        Properties props = System.getProperties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtps.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        Session session = Session.getInstance(props, null);

        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        message.setRecipients(Message.RecipientType.TO, toAddress);
        message.setSubject("JavaMail Attachment");
        BodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setText("Here's the file");
        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(messageBodyPart);
        messageBodyPart = new MimeBodyPart();
        DataSource source = new FileDataSource(filename);
        messageBodyPart.setDataHandler(new DataHandler(source));
        messageBodyPart.setFileName(filename);
        multipart.addBodyPart(messageBodyPart);
        message.setContent(multipart);

        try {
            Transport tr = session.getTransport("smtps");
            tr.connect(host, from, Password);
            tr.sendMessage(message, message.getAllRecipients());
            System.out.println("Mail Sent Successfully");
            tr.close();
        } catch (SendFailedException sfe) {
            System.out.println(sfe);
        }
    }
}` 

【问题讨论】:

    标签: java jakarta-mail


    【解决方案1】:

    好吧,我已经有一段时间没有完成 JavaMail 工作了,但看起来您可以多次重复此代码:

    DataSource source = new FileDataSource(filename);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(filename);
    multipart.addBodyPart(messageBodyPart);
    

    例如,您可以编写一个方法来做到这一点:

    private static void addAttachment(Multipart multipart, String filename)
    {
        DataSource source = new FileDataSource(filename);
        BodyPart messageBodyPart = new MimeBodyPart();        
        messageBodyPart.setDataHandler(new DataHandler(source));
        messageBodyPart.setFileName(filename);
        multipart.addBodyPart(messageBodyPart);
    }
    

    然后从您的主代码中调用:

    addAttachment(multipart, "file1.txt");
    addAttachment(multipart, "file2.txt");
    

    【讨论】:

    • 这似乎不起作用。它只添加最后附加的文件(在这种情况下,电子邮件只有 file2.txt)
    • 我们可以通过传递参数来迭代它,而不是调用单独的方法。
    • @Deva:恐怕我根本不明白你的评论。迭代什么,并将哪些参数传递给什么?请注意,OP 没有要迭代的集合 - 他们只想添加多个单独的附件。
    • 我的意思是,在上面的示例中,您调用了 addAttachment() 2 次。所以,我只是建议您可以将多部分和文件名作为对象数组并通过传递索引参数(如 addAttachment(multipartArray[i], fileArray[i]);
    • @Deva:是的,如果你已经在一个数组中拥有它们。尽管如此,创建一个数组只是为了做到这一点没有什么意义——而且我没有看到任何证据表明 OP 的源代码就是这种情况。 (这仍然会调用一个单独的方法,所以我不确定我是否理解您评论中的“而不是调用单独的方法”部分。)
    【解决方案2】:

    更新(2020 年 3 月)

    使用最新的JavaMail™ API目前是 1.6 版JSR 919),事情就简单多了:


    有用的阅读

    这里有一个很好的教程和完整的例子:

    【讨论】:

    • 是的,但它如何允许我们发送多个文件?
    【解决方案3】:
        Multipart mp = new MimeMultipart();
    
            MimeBodyPart mbp1 = new MimeBodyPart();
            mbp1.setContent(body,"text/html");
            mp.addBodyPart(mbp1);
    
            if(filename!=null)
            {
                MimeBodyPart mbp2 = null;
                FileDataSource fds =null;
                for(int counter=0;counter<filename.length;counter++)
                {
                    mbp2 = null;
                    fds =null;
                    mbp2=new MimeBodyPart();
                    fds = new FileDataSource(filename[counter]);
                    mbp2.setDataHandler(new DataHandler(fds));
                    mbp2.setFileName(fds.getName());
                    mp.addBodyPart(mbp2);
                }
            }
            msg.setContent(mp);
            msg.setSentDate(new Date());
            Transport.send(msg);
    

    【讨论】:

    • 你应该总是解释你提交的代码
    【解决方案4】:

    只需使用要附加的第二个文件的文件名添加另一个块并将其插入到 message.setContent(multipart) 命令之前

        messageBodyPart = new MimeBodyPart();
    
        DataSource source = new FileDataSource(filename);
    
        messageBodyPart.setDataHandler(new DataHandler(source));
    
        messageBodyPart.setFileName(filename);
    
        multipart.addBodyPart(messageBodyPart);
    

    【讨论】:

      【解决方案5】:

      有一个数组列表,其中包含您需要邮寄的附件列表,并使用下面给定的代码

      for(int i=0;i<al.size();i++)
                  {
                      System.out.println(al.get(i));
      
                      messageBodyPart = new MimeBodyPart();
                      DataSource source = new FileDataSource((String)al.get(i));
      
                      messageBodyPart.setDataHandler(new DataHandler(source));
                      messageBodyPart.setFileName((String)al.get(i));
                      multipart.addBodyPart(messageBodyPart);
                      message.setContent(multipart);
                  }
      

      【讨论】:

        【解决方案6】:
        File f = new File(filepath);
        File[] attachments = f.listFiles();
        // Part two is attachment
        for( int i = 0; i < attachments.length; i++ ) {
            if (attachments[i].isFile() && attachments[i].getName().startsWith("error"))  {
                messageBodyPart = new MimeBodyPart();
                FileDataSource fileDataSource =new FileDataSource(attachments[i]);
                messageBodyPart.setDataHandler(new DataHandler(fileDataSource));
                messageBodyPart.setFileName(attachments[i].getName());
                messageBodyPart.setContentID("<ARTHOS>");
                messageBodyPart.setDisposition(MimeBodyPart.INLINE);
                multipart.addBodyPart(messageBodyPart);
            }
        }
        

        【讨论】:

          【解决方案7】:

          只需将更多文件添加到multipart

          【讨论】:

            【解决方案8】:

            这在 Spring 4+ 中 100% 正常工作。您必须在您的 gmail 帐户上启用不太安全的选项。您还需要 apache commons 包:

            <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.4</version>
            </dependency>
            
            @GetMapping("/some-mapping")
            public void mailMethod(@RequestParam CommonsMultipartFile attachFile, @RequestParam CommonsMultipartFile attachFile2) {
            
                Properties mailProperties = new Properties();
                mailProperties.put("mail.smtp.auth", true);
                mailProperties.put("mail.smtp.starttls.enable", true);
                mailProperties.put("mail.smtp.ssl.enable", true);
                mailProperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
                mailProperties.put("mail.smtp.socketFactory.fallback", false);
            
                JavaMailSenderImpl javaMailSenderImpl = new JavaMailSenderImpl();
                javaMailSenderImpl.setJavaMailProperties(mailProperties);
                javaMailSenderImpl.setHost("smtp.gmail.com");
                javaMailSenderImpl.setPort(465);
                javaMailSenderImpl.setProtocol("smtp");
                javaMailSenderImpl.setUsername("*********@gmail.com");
                javaMailSenderImpl.setPassword("*******");
                javaMailSenderImpl.setDefaultEncoding("UTF-8");
            
                List<CommonsMultipartFile> attachments = new ArrayList<>();
                attachments.add(attachFile);
                attachments.add(attachFile2);
            
                javaMailSenderImpl.send(mimeMessage -> {
            
                    MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
                    messageHelper.setTo(emailTo);
                    messageHelper.setSubject(subject);
                    messageHelper.setText(message);
            
                    if (!attachments.equals("")) {
                        for (CommonsMultipartFile file : attachments) {
                            messageHelper.addAttachment(file.getOriginalFilename(), file);
                        }
                    }
                });
            }
            

            【讨论】:

              【解决方案9】:
               for (String fileName: files) {
                          MimeBodyPart messageAttachmentPart = new MimeBodyPart();
                          messageAttachmentPart.attachFile(fileName);
                          multipart.addBodyPart(messageAttachmentPart);
                      }
              

              您必须确保为每个附件创建一个新的 mimeBodyPart。该对象是通过引用传递的,所以如果你只这样做:

               MimeBodyPart messageAttachmentPart = new MimeBodyPart();
                
               for (String fileName: files) {
                          messageAttachmentPart.attachFile(fileName);
                          multipart.addBodyPart(messageAttachmentPart);
                      }
              

              它将附加同一个文件 X 次

              @informatik01 在上面发布了一个答案,其中包含指向文档的链接,其中有一个示例

              【讨论】:

                【解决方案10】:
                 Multipart multipart = new MimeMultipart("mixed");
                
                        for (int alen = 0; attlen < attachments.length; attlen++) 
                        {
                
                            MimeBodyPart messageAttachment = new MimeBodyPart();    
                            fileName = ""+ attachments[attlen];
                
                
                            messageAttachment.attachFile(fileName);
                            messageAttachment.setFileName(attachment);
                            multipart.addBodyPart(messageAttachment);
                
                        }
                

                【讨论】:

                  【解决方案11】:

                  Java Mail 1.3 后附加文件更简单,

                  • 只需使用 MimeBodyPart 方法直接或从文件路径附加文件。

                    MimeBodyPart messageBodyPart = new MimeBodyPart();
                    
                    //messageBodyPart.attachFile(String filePath);
                    messageBodyPart.attachFile(File file);
                    
                    multipart.addBodyPart(messageBodyPart);
                    

                  【讨论】:

                    【解决方案12】:

                    试试这个从数组中读取文件名

                     MimeBodyPart messageBodyPart =  new MimeBodyPart();      
                         Multipart multipart = new MimeMultipart();
                    
                         for(int i = 0 ; i < FilePath.length ; i++){
                              info("Attching the file + "+ FilePath[i]);
                              messageBodyPart.attachFile(FilePath[i]);
                              multipart.addBodyPart(messageBodyPart);                       
                         }         
                     message.setContent(multipart);
                    

                    【讨论】:

                      【解决方案13】:

                      我确实有一个更好的选择,可以在一封邮件中发送多个文件。 Mutipart 类允许我们很容易地实现这个特性。如果您可能没有任何相关信息,请从此处阅读:https://docs.oracle.com/javaee/6/api/javax/mail/Multipart.html

                      Multipart 类为我们提供了两个具有不同参数的同名方法,即 addBodyPart(BodyPart part) 和 addBodyPart(BodyPart part, int index)。对于一个单个文件,我们可以使用第一种方法,对于多个文件,我们可以使用第二种方法(它需要两个参数)。

                       MimeMessage message = new MimeMessage(session);
                                  Multipart multipart = new MimeMultipart();
                      
                                  message.setFrom(new InternetAddress(username));
                      
                                  for (String email : toEmails) {
                                      message.addRecipient(Message.RecipientType.BCC, new InternetAddress(email));
                                      }
                      
                                      message.setSubject(subject);
                                      BodyPart messageBodyPart1 = new MimeBodyPart();
                                      messageBodyPart1.setText(typedMessage);
                      
                                      multipart.addBodyPart(messageBodyPart1, i);
                                      i = i + 1;
                      
                                      for (String filename : attachedFiles) {
                                          MimeBodyPart messageBodyPart2 = new MimeBodyPart();
                      
                      
                                          messageBodyPart2.attachFile(filename);
                      
                                          multipart.addBodyPart(messageBodyPart2, i);
                                          i = i + 1;
                                      }
                      
                                      message.setContent(multipart);
                                      Transport.send(message);
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-04-29
                        • 2011-05-07
                        • 2020-01-14
                        • 1970-01-01
                        相关资源
                        最近更新 更多