Total Pageviews

Showing posts with label Java Mail. Show all posts
Showing posts with label Java Mail. Show all posts

2016/10/04

[Java Mail] com.sun.mail.smtp.SMTPSendFailedException: 452 message processing failed: connection timeout

Problem
I am using JavaMail to send email. But I got this error message as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
DEBUG SMTP: MessagingException while sending, THROW: 
com.sun.mail.smtp.SMTPSendFailedException: 452 message processing failed: connection timeout

 at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2203)
 at com.sun.mail.smtp.SMTPTransport.finishData(SMTPTransport.java:1981)
 at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1197)
 at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:448)
 at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
 at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)
 at com.yuantalife.ecp.commons.service.EmailService.send(EmailService.java:260)


How-to
This is not program's problem. This error may resulted from SMTP server. 
It may :

  1. The ISP server’s disk system has run out of storage space, so the action had to be cancelled.
  2. Most ISPs mail servers impose a maximum number of concurrent connections that client’s mail servers can attempt to make, and they usually also have a limit on the number of messages that are sent per connection.
  3. This error can also be indicative of a problem on your own mail server. ex. out of memory.

Reference
[1] http://www.answersthatwork.com/Download_Area/ATW_Library/Networking/Network__3-SMTP_Server_Status_Codes_and_SMTP_Error_Codes.pdf

2016/08/05

[Java Mail] Encoding problem

Problem
I am using Java Mail API to sent test mail.
Assume I write email content with Traditional Chinese, all characters are broken.


How-To
We need to set default encoding to 'UTF-8' before send.
Here has the sample code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.io.File;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

public class MailTest {

    public static void main(String[] args) {

        Properties props = new Properties();
        props.put("mail.smtp.starttls.enable", "true");

        String host = "smtp.gmail.com";
        int port = 587;
        String userName = "xxx";
        String password = "xxx";

        String mailTo = "xxx@gmail.com";
        String subject = "Hello my friend~";

        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setJavaMailProperties(props);
        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(userName);
        sender.setPassword(password);

        // set email default encoding
        sender.setDefaultEncoding("UTF-8");

        String content = "<p>親愛的客戶您好:</p>";
        content += "<p>您的網路申請驗證碼為<font color='red'>12345</font>,僅限會員申請使用,請於收到e-mail <font color='red'>10分鐘內完成驗證,10分鐘後將自動失效</font></p>";
        content += "<p>XXXX敬上</p>";

        MimeMessage message = sender.createMimeMessage();
        try {

            MimeMessageHelper helper;
            helper = new MimeMessageHelper(message, true);
            helper.setTo(mailTo);
            helper.setSubject(subject);

            // true means it is a html format email
            helper.setText(content, true);

     // attachment1
            FileSystemResource panda01 = new FileSystemResource(new File(
                    "D://dropbox//picture//201602011033331.png"));
            helper.addInline("pand01", panda01);

     // attachment2
            FileSystemResource panda02 = new FileSystemResource(new File(
                    "D://dropbox//picture//panda.png"));
            helper.addInline("panda02", panda02);

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }

 //sent mail
        sender.send(message);
    }
}

Check the mail:

Reference
[1] http://stackoverflow.com/questions/5636255/unicode-chars-and-spring-javamailsenderimpl-no-unicode-chars-under-linux

2016/08/04

[JavaMail] Attachment name does not show correctly in Email

Problem
I am using JavaMail API to send email. But the attachment name does not show correctly.
The name should be 退匯明細表.pdf‎, but I got ATT97145.pdf‎.

The incorrect email looks like:


The expected email looks like:


Here is the code snippet to add attachment in email:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
private void attachFiles(MimeMessageHelper messageHelper, List<File> attachFiles)
        throws MessagingException {
    for (File attachFile : attachFiles) {
        FileSystemResource file = new FileSystemResource(attachFile);
        log.info("attachFile.getName():" + attachFile.getName());

        try {
            messageHelper.addAttachment(attachFile.getName(), file);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}


Solution
You can utilize MimeUtility.encodeText to handle the file name.
Here is the updated code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
private void attachFiles(MimeMessageHelper messageHelper, List<File> attachFiles)
        throws MessagingException {
    for (File attachFile : attachFiles) {
        FileSystemResource file = new FileSystemResource(attachFile);
        log.info("attachFile.getName():" + attachFile.getName());

        try {
            messageHelper.addAttachment(
                    MimeUtility.encodeText(attachFile.getName(), "UTF-8", null), file);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}


Reference
[1] http://docs.oracle.com/javaee/6/api/javax/mail/internet/MimeUtility.html#encodeText(java.lang.String, java.lang.String, java.lang.String)

2016/08/03

[Java Mail] How to check Exchange Server status?

Problem
If I would like to write a Java code to check the status of SMTP server, how to do it?

How-to
The sample code is as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package albert.practice.mail;

import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;

import lombok.extern.slf4j.Slf4j;

import org.springframework.mail.javamail.JavaMailSenderImpl;

/**
 * Used to check the status of exchange server .
 */
@Slf4j
public class CheckSmtpStatus {

    /**
     * The main method.
     * 
     * @param args
     *            the arguments
     * @throws MessagingException
     *             the messaging exception
     */
    public static void main(String[] args) throws MessagingException {
        String host = "smtp host name";
        int port = 25;
        String emailU = "username";
        String emailP = "password";

        CheckSmtpStatus checkSmtpStatus = new CheckSmtpStatus();
        boolean isConnected = checkSmtpStatus.isConnected(host, port, emailU, emailP);
        log.debug("isConnected = " + isConnected);
    }

    /**
     * Checks if is connected.
     * 
     * @param host
     *            the host
     * @param port
     *            the port
     * @param emailU
     *            the email u
     * @param emailP
     *            the email p
     * @return true, if is connected
     * @throws MessagingException
     *             the messaging exception
     */
    public boolean isConnected(String host, int port, String emailU, String emailP)
            throws MessagingException {
        boolean isConnected = false;
        Transport transport = null;
        Session session = createJavaMailSender(host, port, emailU, emailP);
        try {
            transport = session.getTransport("smtp");
            transport.connect(host, port, emailU, emailP);

            // used to check this SMTP service is currently connected or not
            isConnected = transport.isConnected();
        } catch (NoSuchProviderException e) {
            throw new RuntimeException(e);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        } finally {
            transport.close();
        }
        return isConnected;
    }

    private Session createJavaMailSender(String host, int port, String emailU, String emailP) {
        Properties properties = new Properties();
        properties.setProperty("mail.debug", "true");
        properties.setProperty("mail.smtp.auth", "true");
        properties.put("mail.smtp.ssl.trust", "*");

        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setJavaMailProperties(properties);
        javaMailSender.setHost(host);
        javaMailSender.setPort(port);
        javaMailSender.setDefaultEncoding("UTF-8");
        javaMailSender.setUsername(emailU);
        javaMailSender.setPassword(emailP);

        return javaMailSender.getSession();
    }

}




2016/07/08

[JavaMail] How to send email via Microsoft Exchange Server?

Problem
I am using JavaMail to write program to send email via Microsoft Exchange Server. How to do it?

How-to
The sample code looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package albert.practice.mail;

import java.io.File;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import lombok.extern.slf4j.Slf4j;

import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import albert.practice.mail.params.EmailParams;

@Slf4j
public class ExchangeServerMailTest {

    public static void main(String[] args) {
        // set email parameters
        EmailParams params = new EmailParams();
        params.setReceiverEmail("email address");
        params.setSubject("測試一下");
        params.setContent("測試測試測試測試");

        // call sendMail API
        new ExchangeServerMailTest().sendMail(params);
    }

    public void sendMail(EmailParams params) {
        JavaMailSenderImpl sender = getJavaMailSender();
        MimeMessage message = sender.createMimeMessage();

        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setTo(params.getReceiverEmail());
            helper.setFrom("email address");
            helper.setSubject(params.getSubject());
            helper.setText(params.getContent(), false);

            // set attachment
            FileSystemResource attachment = new FileSystemResource(new File(
                    "D:\\dropbox\\退匯明細表.pdf"));
            helper.addAttachment("退匯明細表.pdf", attachment);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        sender.send(message);

        log.debug("mail sent..");
    }

    private JavaMailSenderImpl getJavaMailSender() {
        Properties props = new Properties();
        props.put("mail.smtp.auth", true);
        props.put("mail.smtp.ssl.trust", "*");

        // mail server configuration
        String host = "your smtp";
        int port = 25;
        String userName = "your user name";
        String password = "your password";

        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setJavaMailProperties(props);
        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(userName);
        sender.setPassword(password);
        sender.setDefaultEncoding("UTF-8");

        return sender;
    }

}




2016/07/07

[JavaMail] javax.mail.MessagingException: Could not convert socket to TLS

Problem
I am using JavaMail set send email via Microsoft Exchange Server.
When I run this program, it show this error message:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Exception in thread "main" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; message exception details (1) are:
Failed message 1:
javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1907)
 at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:666)
 at javax.mail.Service.connect(Service.java:295)
 at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:501)
 at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:421)
 at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
 at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)
 at albert.practice.mail.ExchangeServerMailTest.sendMail(ExchangeServerMailTest.java:49)
 at albert.practice.mail.ExchangeServerMailTest.main(ExchangeServerMailTest.java:28)

The code snippet looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
   private JavaMailSenderImpl getJavaMailSender() {
        Properties props = new Properties();
        props.put("mail.smtp.auth", true);

        // mail server configuration
        String host = "your smtp";
        int port = 25;
        String userName = "your user name";
        String password = "your password";

        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setJavaMailProperties(props);
        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(userName);
        sender.setPassword(password);
        sender.setDefaultEncoding("UTF-8");

        return sender;
    } 



How-To
You need to set mail.smtp.ssl.trust in your JavaMail properties.
If set, and a socket factory hasn't been specified, enables use of a MailSSLSocketFactory. 
If set to "*", all hosts are trusted. 
If set to a whitespace separated list of hosts, those hosts are trusted. Otherwise, trust depends on the certificate the server presents.


The updated code snippet looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    private JavaMailSenderImpl getJavaMailSender() {
        Properties props = new Properties();
        props.put("mail.smtp.auth", true);
        // Fix Excpetion: Mail server connection failed; nested exception is
        // javax.mail.MessagingException: Could not convert socket to TLS
        // If set, and a socket factory hasn't been specified, enables use of a
        // MailSSLSocketFactory. If set to "*", all hosts are trusted. If set to a whitespace
        // separated list of hosts, those hosts are trusted. Otherwise, trust depends on the
        // certificate the server presents.
        props.put("mail.smtp.ssl.trust", "*");

        // mail server configuration
        String host = "your smtp";
        int port = 25;
        String userName = "your user name";
        String password = "your password";

        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setJavaMailProperties(props);
        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(userName);
        sender.setPassword(password);
        sender.setDefaultEncoding("UTF-8");

        return sender;
    } 


Reference
[1] https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html

2016/04/10

[Java Mail] Embed Images into Email

Requirement
If we would like embed a image file into Email as bellows:

How to do it?

How-To
In the velocity template file, we define a image tag and define a cid (content id):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<html>
   <body>
      <p>親愛的保戶您好</p>
      <p>     </p>
      <p>感謝您對xxxx的支持,您在網路上申請的旅平險保單已投保完成,以下是您的投保明細,供您參考。</p>
      <p>【投保內容】</p>
      <p>保單號碼: ${customer.policyNumber}</p>
      <p>被保險人: ${customer.name}</p>
      <p>申請日期: ${customer.applyDate}</p>
      <p>保險期間: ${customer.fromDate} ~ ${customer.toDate}</p>
      <p>旅遊地點: ${customer.place}</p>
      <p></p>
      <p>※保險單及保險費送金單將於近日內寄至要保人所指定之聯絡地址。</p>
      <p></p>
      <p>                     敬祝  闔家平安 </p>
      <p><img src="cid:panda"></p>
   </body>
</html>

Here is code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
 public static void main(String[] args) throws IOException, MessagingException {

  ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
  VelocityEngine velocityEngine = (VelocityEngine) context.getBean("velocityEngine");

  // set value to template
  Customer customer = new Customer();
  customer.setPolicyNumber("12345678");
  customer.setName("測試");
  customer.setApplyDate("20160325");
  customer.setFromDate("20160401");
  customer.setToDate("20160410");
  customer.setPlace("日本關西");

  // set customer to map for velocity email template
  Map<String, Object> model = new HashMap<String, Object>();
  model.put("customer", customer);

  // get email content from velocity email template
  String mailTemplate = "albert/practice/mail/templates/insurance.vm";
  String content = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, mailTemplate, "UTF-8", model);

  // set file attachments
  File pdfFile = new File("/Users/albert/Dropbox/Getting Started.pdf");
  File mindmapFile = new File("/Users/albert/Dropbox/eBooks//The Intelligent Investor.png");

  List<File> attachments = new ArrayList<File>();
  attachments.add(pdfFile);
  attachments.add(mindmapFile);

  // set email parameters
  EmailParams params = new EmailParams();
  params.setReceiverEmail("junyuo@gmail.com");
  params.setSubject("網路投保完成通知");
  params.setContent(content);
  params.setAttachments(attachments);

  new MailTest().sendMail(params);
 }

 public void sendMail(EmailParams params) {

  JavaMailSenderImpl sender = getJavaMailSender();
  MimeMessage message = sender.createMimeMessage();

  List<File> attachemtns = null;

  try {
   MimeMessageHelper helper = new MimeMessageHelper(message, true);
   helper.setTo(params.getReceiverEmail());
   helper.setSubject(params.getSubject());
   helper.setText(params.getContent(), true);

   // add attachment(s)
   if (params.getAttachments() != null && params.getAttachments().size() > 0) {
    attachemtns = params.getAttachments();
    for (int i = 0; i < attachemtns.size(); i++) {
     FileSystemResource attachment = new FileSystemResource(attachemtns.get(i));
     helper.addAttachment(attachemtns.get(i).getName(), attachment);
    }
   }

   // embed image in email
   InputStreamSource logo = new ByteArrayResource(
     IOUtils.toByteArray(getClass().getResourceAsStream("img/panda.png")));
   helper.addInline("panda", logo, "image/png");

  } catch (MessagingException e) {
   throw new RuntimeException(e);
  } catch (IOException e) {
   throw new RuntimeException(e);
  }
  sender.send(message);
  System.out.println("mail sent..");
 }

 

 private JavaMailSenderImpl getJavaMailSender() {
  // enable starttls
  Properties props = new Properties();
  props.put("mail.smtp.starttls.enable", "true");

  // mail server configuration
  String host = "smtp.gmail.com";
  int port = 587;
  String userName = "xxxx";
  String password = "xxxx";

  JavaMailSenderImpl sender = new JavaMailSenderImpl();
  sender.setJavaMailProperties(props);
  sender.setHost(host);
  sender.setPort(port);
  sender.setUsername(userName);
  sender.setPassword(password);
  sender.setDefaultEncoding("UTF-8");

  return sender;
 }

Remember to update your maven dependency:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 <!-- email -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>jaf</groupId>
            <artifactId>activation</artifactId>
            <version>1.0.2</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mail</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>

        <!-- velocity -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>


Reference
[1] http://www.rgagnon.com/javadetails/java-0504.html