Java: String changes so name for all items change in for-loop

I have the following code to send an email with multiple parts

 public void sendEmail(String emailAddress, List<String> attachment) throws Exception{
    Properties props = new Properties();

    props.put("mail.transport.protocol", "smtps");
    props.put("mail.smtps.host", SMTP_HOST_NAME);
    props.put("mail.smtps.auth", "true");

    Session mailSession = Session.getDefaultInstance(props);
    mailSession.setDebug(true);
    Transport transport = mailSession.getTransport();

    MimeMessage message = new MimeMessage(mailSession);
    // message subject
    message.setSubject("Automated email from Kieran Herley about Assignments");

    message.addRecipient(Message.RecipientType.TO,
         new InternetAddress(emailAddress));

    Multipart multipart = new MimeMultipart();
    MimeBodyPart messageBodyPart = new MimeBodyPart();

    // message body
    messageBodyPart.setText("This is just a message to say your assignment has been graded.\nAttached is a file with some pointers about your assignment");
    multipart.addBodyPart(messageBodyPart);

    messageBodyPart = new MimeBodyPart();

    for (String singleFile : attachment) {
        DataSource source = new FileDataSource(singleFile);
        messageBodyPart.setDataHandler(new DataHandler(source));
        String nameOfFile = singleFile.substring(singleFile.lastIndexOf('\\') + 1);
        messageBodyPart.setFileName(nameOfFile);
        multipart.addBodyPart(messageBodyPart);
    }
    message.setContent(multipart);


    transport.connect(SMTP_HOST_NAME, SMTP_HOST_PORT, SMTP_AUTH_USER, SMTP_AUTH_PWD);

    transport.sendMessage(message,
        message.getRecipients(Message.RecipientType.TO));
    transport.close();
}

Everything is working fine but the problem i am having is in the for-loop

for (String singleFile : attachment) {
        DataSource source = new FileDataSource(singleFile);
        messageBodyPart.setDataHandler(new DataHandler(source));
        String nameOfFile = singleFile.substring(singleFile.lastIndexOf('\\') + 1);
        messageBodyPart.setFileName(nameOfFile);
        multipart.addBodyPart(messageBodyPart);
    }
    message.setContent(multipart);

The problem that i am having is, if the application loops through the for-loop 3 times, it will name all the files attached to the email the name of the file that was passed through the loop the third time. This is also the same with the email attachment itself, even do it is sending 3 attachments, they are all named the same.

This is because all three of the attachments are using the same variable to both name them and retrieve so for all three of them it is naming them and setting them as the last one passed through the loop.

Is there a way to set the name and attachment of each email by using the same name variable and attachment variable for all, or how would I do this?

In this case use

String singleFile --- for the attachment
String nameOfFile --- for the name of each file

Answers


This looks like nothing wrong with strings in for-each loop. My concern that you always using the same instance of messageBodyPart when assign datahandler and filename to it. Try to move messageBodyPart = new MimeBodyPart() inside the loop.


I'm not sure I understand what you need, but it would probably make sense to have this line:

messageBodyPart = new MimeBodyPart();

inside the for loop, rather than before. At the moment, you keep adding the same body part to multipart.


Need Your Help

Are there any IoC frameworks that do not use JIT compilation that support interception?

c# dependency-injection inversion-of-control jit

It seems that Mono on iOS does not support JIT compilation, which seems to be used by at least StructureMap, Ninject, and Simple Injector. It can be turned off with reflection replacing it in Ninje...

LibGDX - Multitouch handling using InputProcessor

java android libgdx multi-touch

I am trying to set up proper multitouch support in my android game for some time. For input handling I use my InputHandler(implementing InputProcessor). I use something like this