Link to home
Start Free TrialLog in
Avatar of LeanMoreTryMore
LeanMoreTryMore

asked on

Failed to send email with the attachment (PDF file)

I have no idea why the email is sent but no attachement. No error

Please advise and correct my code. Notes that the attachement is in PDF format. It does send email but no attachment.

AttachedFileName = c:\VSCO.pdf

  public static int MSoutlookSend(String to
                                 ,String from
                                 ,String host
                                 ,String loginUser
                                 ,String loginPwd
                                 ,String msgText1
                                 ,String msgText2
                                 ,String AttachedFileName) throws Exception {

     // boolean debug = Boolean.valueOf(args[3]).booleanValue();

     // create some properties and get the default Session
     Properties props = new Properties();
     props.put("mail.smtp.host", host);
     props.put("mail.smtp.auth", "true");

     Session session = Session.getDefaultInstance(props, null);
     //session.setDebug(debug);
     try {
       // create a message
       MimeMessage msg = new MimeMessage(session);
       InternetAddress[] address = {new InternetAddress(to)};
       msg.setFrom(new InternetAddress(from));
       msg.setRecipients(Message.RecipientType.TO, address);
       msg.setSubject("2000Plus Scheduler");
       msg.setSentDate(new Date());
       msg.setText(msgText1);

       // Handle attachment
       // send the message
       Transport transport = session.getTransport("smtp");
       /*
       System.out.println("host => " + host +
                          " | loginUser => " + loginUser +
                          " | loginPwd  => " + loginPwd);
       */
       transport.connect(host, loginUser, loginPwd);
       msg.saveChanges();

       if ( ! msgText2.equals("NULL")) {

          System.out.println("msgText2 IS NOT NULL");

          // create and fill the first message part
          MimeBodyPart mbp1 = new MimeBodyPart();
          mbp1.setText(msgText1);
          // create the Multipart and its parts to it
          Multipart mp = new MimeMultipart();
          mp.addBodyPart(mbp1);
          // add the Multipart to the message
          // create and fill the second message part
          // Handle attachment
          if (!AttachedFileName.equalsIgnoreCase("NULL")) {
             System.out.println("attachment found");
             MimeBodyPart mbp2 = new MimeBodyPart();
             String filename = AttachedFileName;
             File attachments = new File(filename);
             FileDataSource fileDataSource = new FileDataSource(attachments);
             mbp2.setDataHandler(new DataHandler(fileDataSource));
             mbp2.setFileName(AttachedFileName);
             mp.addBodyPart(mbp2);
          }
          msg.setContent(mp);
       }

       transport.sendMessage(msg, msg.getAllRecipients());
       transport.close();
     }
     catch (AddressException ae) {
         System.out.println("address exception Error occured due to " + ae);
         ae.printStackTrace();
         Exception ex = null;
         if ((ex = ae.getNextException()) != null) {
             ex.printStackTrace();
         }
         return 1;
     }
     return 0;
   } // MSoutlookSend
Avatar of Jim Cakalic
Jim Cakalic
Flag of United States of America image

Hi. What's the value of msgText2? I ask because you've made the inclusion of the attachment dependent on msgText2 having a non-null value. Is that what you intended?

Otherwise, the problem may stem from your failure to set mime content types correctly. First, the use of MimeMessage.setText is a convenience method that ends up setting the Content-Type header of the MimeMessage to "text/plain". From that point forward, I think you're bound to have only the text for msgText1 as part of your email. Also, when creating a multipart message, especially one with attachments, you need to set the Content-Type of each subpart explicitly.

I'm not sure this exactly works as I'm working from memory. And I'm a little uncertain as to what to do with the two text parts other then make each it's own MimeBodyPart. But here's what I think you could do:

    public static int MSoutlookSend(
            String to, String from, String host,
            String loginUser, String loginPwd,
            String msgText1, String msgText2, String AttachedFileName)
            throws Exception {

        // boolean debug = Boolean.valueOf(args[3]).booleanValue();

        // create some properties and get the default Session
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.auth", "true");
        Session session = Session.getDefaultInstance(props, null);
        //session.setDebug(debug);

        try {
            // create a message
            MimeMessage msg = new MimeMessage(session);
            msg.setHeader("Content-Type", "multipart/mixed");
            InternetAddress[] address = { new InternetAddress(to) };
            msg.setFrom(new InternetAddress(from));
            msg.setRecipients(Message.RecipientType.TO, address);
            msg.setSubject("2000Plus Scheduler");
            msg.setSentDate(new Date());

            Transport transport = session.getTransport("smtp");
            /*
             * System.out.println("host => " + host + " | loginUser => " +
             * loginUser + " | loginPwd => " + loginPwd);
             */
            transport.connect(host, loginUser, loginPwd);

            Multipart mp = new MimeMultipart();
            if (msgText1 != null && !msgText1.equals("NULL")) {
                MimeBodyPart mbp = new MimeBodyPart();
                mbp.setText(msgText1);
                mbp.setHeader("Content-Type", "text/plain");
                mp.addBodyPart(mbp);
            }
            if (msgText2 != null && !msgText2.equals("NULL")) {
                MimeBodyPart mbp = new MimeBodyPart();
                mbp.setText(msgText2);
                mbp.setHeader("Content-Type", "text/plain");
                mp.addBodyPart(mbp);
            }
            if (AttachedFileName != null && AttachedFileName.equalsIgnoreCase("NULL")) {
                MimeBodyPart mbp = new MimeBodyPart();
                mbp.setHeader("Content-Type", "application/octet-stream");
                File attachments = new File(AttachedFileName);
                FileDataSource fileDataSource = new FileDataSource(attachments);
                mbp.setDataHandler(new DataHandler(fileDataSource));
                mbp.setFileName(AttachedFileName);
                mp.addBodyPart(mbp);
            }
            msg.setContent(mp);

            transport.sendMessage(msg, msg.getAllRecipients());
            transport.close();
        } catch (AddressException ae) {
            System.out.println("address exception Error occured due to " + ae);
            ae.printStackTrace();
            Exception ex = null;
            if ((ex = ae.getNextException()) != null) {
                ex.printStackTrace();
            }
            return 1;
        }
        return 0;
    } // MSoutlookSend

Notice that I set the Content-Type header for the message itself as well as for each MimeBodyPart created. Again, I wasn't sure what to do with the fact that you had two text parts. And maybe it was error that, in the original you posted, the bit that dealt with msgText2 ended up setting the MimeBodyPart text to msgText1? Or maybe it was something I didn't understand about the intent.

Anyway, maybe you could give this a try and get back to me.

Regards,
Jim Cakalic

Avatar of LeanMoreTryMore
LeanMoreTryMore

ASKER

Thank Jim,

I used the code as advised. The content of the email like below

------=_Part_0_31682.1109560231603
Content-Type: text/plain

------=_Part_0_31682.1109560231603--


===========================================================================
One more question how to add a carriage return character. I add \n  but does not work

Please advise. Thanks
The \n is just newline. You could use \r\n to get carriage-return + newline. Or you could get the value of the System property line.separator and use that to make your code platform independent:
    String newline = System.getProperty("line.separator");

So I'm not clear from your last post. Did the changes correct your attachment problem?

Jim
Thanks.

It still have a problem email with the PDF attachment. No attachment is found and the content of the email is as below


------=_Part_0_31682.1109560231603
Content-Type: text/plain

------=_Part_0_31682.1109560231603--


I used your codes as advised.
Hi Jim,

It works. Thanks

May I ask you one last question?

What do you expect from the developer if they say they knows J2EE?
Umm, replace the AttachedFileName bit with this:

            if (AttachedFileName != null && !AttachedFileName.equalsIgnoreCase("NULL")) {
                MimeBodyPart mbp = new MimeBodyPart();
                mbp.setHeader("Content-Type", "application/pdf");
                File attachments = new File(AttachedFileName);
                FileDataSource fileDataSource = new FileDataSource(attachments);
                mbp.setDataHandler(new DataHandler(fileDataSource));
                mbp.setFileName(AttachedFileName);
                mp.addBodyPart(mbp);
            }

I think I screwed up the logic from the original.

Jim
That is wat i changed, Jim.
Many thanks. it works perfectly.

Would you please give me some idea about J2EE? I will increase the point to 400 and reward to you.

We need to hire some J2EE developer but dont know what questions we need to ask the ppl.

We all are Oracle developer, recently decide to upgrade our product running on web browser. I think we need J2EE developers.

What do you expect from the developer if they say they knows J2EE?

Hmm. Not an easy question. In part because J2EE is such a smorgasbord of technogolies. I guess, to start, I'd expect that someone claiming to know J2EE has at least been exposed to most of these technologies -- servlets, jsp, jdbc, ejb, html, javascript, jndi, jms. The level to which they might be comfortable in working in these technologies would no doubt differ based on experience. It is also becoming increasingly important to be familiar with XML and the JAX family of XML-related technologies. I'd expect someone with some experience in J2EE also ought to be able to understand the benefits of design patterns like MVC and Layered Architecture.

You might be interested in a new book on this topic.
Conducting the J2EE Job Interview
http://www.bookpool.com/sm/0974435597

Are you asking for yourself -- what should you know -- or for evaluating the skills of others?

Jim
Very thanks. I like to ask you one more question if you dont mond before I close this tar.

Are you asking for yourself -- what should you know -- or for evaluating the skills of others?
a bit for both.

Me and my boss will conduct an interview for a few applicants. And I'm the only one in the team doing all the Java work. But I havent done any development work on J2EE environment

Lets say for me, I know Java, JDBC, JavaMail (API), HTML,XML, JSP (not as good as ASP) and Mobile Phone transaction.
Can I say I know J2EE? or I just know little bit Java

Thanks
ASKER CERTIFIED SOLUTION
Avatar of Jim Cakalic
Jim Cakalic
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This is really good. thank you very much.
At least we have idea wat questions we ask the applicants
My pleasure. Good luck.