Spring Mail常见问题分析和解决办法

背景说明

JDK自带的Mail类库封装的简直就是一坨屎(大家不要骂我),用起来怎么看怎么变扭,所以一开始我就想到了Spring Mail这个优雅的封装集成类库。下面就说说,我使用Spring Mail遇到的几个问题。

核心代码

public void sendMail(List tos, List ccs, String subject, String centent, List attachments){
    JavaMailSenderImpl sender = new JavaMailSenderImpl();
    sender.setHost(host);
    sender.setProtocol("smtp"); //默认是smtp【smtps协议端口465 smtp协议端口25】
    sender.setPort(Integer.parseInt(port));
    sender.setUsername(username);
    sender.setPassword(password);
    Properties mail = System.getProperties();
    mail.put("mail.smtp.auth", "true");
    sender.setJavaMailProperties(mail);
    MimeMessage message = sender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message);
    try {
        helper.setSubject(subject);
        helper.setFrom(username);
        helper.setTo(tos.toArray(new String[]{}));
        if(CollectionUtils.isEmpty(bccs)){
            helper.setCc(bccs.toArray(new String[]{}));
        }
        helper.setText(centent);
        if(!CollectionUtils.isEmpty(attachments)){
            for(File file: attachments){
                if(file.exists() && file.isFile()){
                    FileSystemResource fsr = new FileSystemResource(file);
                    helper.addAttachment(file.getName(), fsr);
                }
                else{
                    log.warn("file: {} is not exists or directory.", file.getPath());
                }
            }
        }
        sender.send(message);
    } catch (MessagingException e) {
        log.error(e.getMessage(), e);
        // 养成一个好习惯,把捕获异常包装为运行时异常,方便调用者
        throw new RuntimeException(e.getMessage(), e);
    }
}

问题一(邮箱发件人设置)

com.sun.mail.smtp.SMTPSendFailedException: 500 Error: bad syntax

Exception in thread "main" org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 500 Error: bad syntax
; message exception details (1) are:
Failed message 1:
com.sun.mail.smtp.SMTPSendFailedException: 500 Error: bad syntax

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1388)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:959)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:583)
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:433)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)

由于平时工作使用邮件不多,一开始遇到这个问题,没看懂这个错误是什么意识,也是弄了好久。最后用蓝灯神器搜到了跟我这个异常差不多的文章。
http://stackoverflow.com/questions/38889504/smtp-protocol-500-error-bad-syntax

  • 总结
    我没有加上helper.setFrom(username); 这段代码。刚开始我以为 sender.setUsername(username);这段代码就是设置了邮件的发送人,可实际上不是的。

问题二(权限认证设置)

com.sun.mail.smtp.SMTPSendFailedException: 553 authentication is required

Exception in thread "main" org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 553 authentication is required
; message exception details (1) are:
Failed message 1:
com.sun.mail.smtp.SMTPSendFailedException: 553 authentication is required

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1388)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:959)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:583)
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:433)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)

这个错误相对于第一个错误来说,还是比较容易懂(认证的问题)。刚开始我以为是邮箱的账号和密码设置有问题,在foxmail中验证了一下没问题,就排除了这个原因。最后只能开启搜索模式啦!
http://www.cnblogs.com/liuling/archive/2013/03/25/asdfasdf.html

  • 总结
    少写了下面这段代码,我估计默认这个mail.smtp.auth属性值是false吧!
Properties mail = System.getProperties();
mail.put("mail.smtp.auth", "true");
sender.setJavaMailProperties(mail);

问题三(协议端口设置)

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection

Exception in thread "main" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Exception reading response;
  nested exception is:
    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?. Failed messages: javax.mail.MessagingException: Exception reading response;
  nested exception is:
    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?; message exception details (1) are:
Failed message 1:
javax.mail.MessagingException: Exception reading response;
  nested exception is:
    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1462)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1260)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:370)
    at javax.mail.Service.connect(Service.java:275)
    at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:486)
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:406)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)

大概意识是,你使用了ssl安全连接协议,但是传输的数据是明文。

sender.setProtocol("smtps"); //默认是smtp【smtps协议端口465 smtp协议端口25】
sender.setPort(25);
  • 总结
    Spring Mail默认使用的是smtp协议,也就是说,如果你不设置邮件协议,端口只能设置为25。
    如果您不是太清楚邮件的设置,可以参考foxmail
    Spring Mail常见问题分析和解决办法_第1张图片
    Spring Mail常见问题分析和解决办法_第2张图片

使用建议

邮件的初始化比较消耗计算机资源,强烈建议在项目中用spring bean的方式来管理,不要像我这样每发一份邮件就初始化一个邮件客户端。这个问题就好比,你是每收发一份邮件打开一次Foxmail还是Foxmail一直开着。

你可能感兴趣的:(SpringMail)