Java 发送邮件,带附件,抄送

 1.依赖

<dependency>
	<groupId>javax.mail</groupId>
	<artifactId>mail</artifactId>
	<version>1.4.7</version>
</dependency>

2.入参

package xxx

import lombok.Data;

import java.util.List;

/**
 * 邮件发送请求
 */
@Data
public class SendMailNewReq extends BaseReq {
    /**
     * 收件人,多个用逗号分隔
     */
    private String recipient;
    /**
     * 抄送人,多个用逗号分隔
     */
    private String ccRecipient;
    /**
     * 邮件主题
     */
    private String subject;
    /**
     * 邮件内容
     */
    private String content;
    /**
     * 附件
     */
    private List<String> filePathList;
}

3.出参 

package xxx

import lombok.Data;

/**
 * 邮件发送响应
 */
@Data
public class SendMailNewRsp {
    /**
     * 发送结果
     * S:成功,F:失败
     */
    private String result;
    /**
     * 失败描述
     */
    private String errorMsg;
}

4.发送邮件实现 

package xxx

import cn.hutool.core.collection.CollectionUtil;
import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.*;

@Slf4j
@Service("mailSendService")
public class MailSendServiceImpl implements MailSendService {

    @Override
    public SendMailRsp sendMail(SendMailReq sendMailReq) {
        SendMailRsp sendMailRsp = new SendMailRsp();

        //SMTP服务器连接信息
        Properties props = new Properties();
        props.setProperty("mail.smtp.host", "smtp.163.com"); //SMTP主机名
        props.setProperty("mail.smtp.port", "465"); //主机端口号
        props.setProperty("mail. Transport.protocol", "smtp"); //邮箱协议
        props.setProperty("mail.smtp.auth", "true"); //是否需要用户认证
        props.setProperty("mail.smtp.ssl.enable", "true"); //启用SSL连接并使用SSL端口
        props.setProperty("mail. Debug", "true");//开启debug模式,可以看到发送日志

        MailSSLSocketFactory sf = null;
        try {
            sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }

        props.put("mail.smtp.ssl.socketFactory", sf);
        props.put("mail.smtp.socketFactory.port", "465");//端口

        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("zhangsan@163.com", "zhangsan123");//账号、密码
            }
        });

        //session.setDebug(true);//开启debug模式,可以看到发送日志

        try {

            //创建邮件对象
            MimeMessage message = new MimeMessage(session);

            // 发件人
            InternetAddress sender = new InternetAddress("zhangsan@163.com");//发送者账号
            sender.setPersonal(MimeUtility.encodeText("张三"));//发送者昵称
            message.setFrom(sender);
            //收件人
            message.setRecipients(Message.RecipientType.TO, getInternetAddress("lisi@163.com,wangwu@163.com"));
            // 抄送
            if (StringUtils.isNotBlank(sendMailReq.getCcRecipient())) {
                message.setRecipients(Message.RecipientType.CC, getInternetAddress("zhaoliu1@163.com,zhaoliu2@163.com"));
            }
            //邮件主题
            message.setSubject("这是邮件主题");

            //正文
            BodyPart textpart = new MimeBodyPart();
            textpart.setContent("这是邮件正文", "text/html;charset=utf-8");

            //构建多重消息
            MimeMultipart mimeMultipart = new MimeMultipart();
            mimeMultipart.addBodyPart(textpart);

            //上传附件文件
            List<String> filePathList = sendMailReq.getFilePathList();//附件,本地文件的路径
            if (CollectionUtil.isNotEmpty(filePathList)) {
                for (String filePath : filePathList) {
                    MimeBodyPart file = new MimeBodyPart();
                    FileDataSource file_datasource = new FileDataSource(filePath);
                    DataHandler dh = new DataHandler(file_datasource);
                    file.setDataHandler(dh);
                    //附件区别内嵌内容的一个特点是有文件名,为防止中文乱码要编码
                    file.setFileName(MimeUtility.encodeText(dh.getName()));
                    mimeMultipart.addBodyPart(file);
                }
            }

            //将multipart对象放入邮箱
            message.setContent(mimeMultipart);
            log.info("【+】【邮件发送】,邮件消息对象message={}", JsonKit.bean2Json(message));

            //发送邮件
            Transport.send(message);

            log.info("邮件发送成功!");
            sendMailRsp.setResult(Constant.COMMON.S);
            sendMailRsp.setErrorMsg("邮件发送成功!");
        } catch (AddressException e) {
            log.info("邮件发送失败,错误原因:" + e.getMessage());
            sendMailRsp.setResult(Constant.COMMON.F);
            sendMailRsp.setErrorMsg("请检查邮箱地址:" + e.getMessage());
        } catch (UnsupportedEncodingException e) {
            log.info("邮件发送失败,错误原因:" + e.getMessage());
            sendMailRsp.setResult(Constant.COMMON.F);
            sendMailRsp.setErrorMsg("转码异常,请查看详细信息" + e.getMessage());
        } catch (NoSuchProviderException e) {
            log.info("邮件发送失败,错误原因:" + e.getMessage());
            sendMailRsp.setResult(Constant.COMMON.F);
            sendMailRsp.setErrorMsg("邮件发送失败,详细错误原因:" + e.getMessage());
        } catch (MessagingException e) {
            log.info("邮件发送失败,错误原因:" + e.getMessage());
            sendMailRsp.setResult(Constant.COMMON.F);
            sendMailRsp.setErrorMsg("邮件发送失败,有可能的问题为服务器url不存在或附件不存在,具体请看详细信息:" + e.getMessage());
        } catch (Exception e) {
            log.info("邮件发送失败,错误原因:" + e.getMessage());
            sendMailRsp.setResult(Constant.COMMON.F);
            sendMailRsp.setErrorMsg("邮件发送失败,有可能的问题为服务器url不存在或附件不存在,具体请看详细信息:" + e.getMessage());
        }

        log.info("【-】【邮件发送】,请求出参={}", JsonKit.bean2Json(sendMailRsp));
        return sendMailRsp;
    }

    private static InternetAddress[] getInternetAddress(String address) throws Exception {
        String[] addressArr = address.split("\\,");
        List<String> list = new ArrayList<>();
        for (String str : addressArr) {
            if (StringUtils.isBlank(str)) {
                continue;
            }
            list.add(str);
        }
        InternetAddress[] internetAddress = new InternetAddress[list.size()];
        for (int i = 0; i < list.size(); i++) {
            internetAddress[i] = new InternetAddress(list.get(i));
        }
        return internetAddress;
    }
}

5.JavaMail配置属性

属性名    含义
mail.smtp.user    SMTP的缺省用户名。
mail.smtp.host    要连接的SMTP服务器。
mail.smtp.port    要连接的SMTP服务器的端口号,如果connect没有指明端口号就使用它,缺省值25。
mail.smtp.auth    缺省是false,如果为true,尝试使用AUTH命令认证用户。
mail.transport.protocol    要装入session的协议(smtp、pop3、imap、nntp)。
mail.smtp.connectiontimeout    Socket连接超时值,单位毫秒,缺省值不超时。
mail.smtp.timeout    Socket I/O超时值,单位毫秒,缺省值不超时。
mail.smtp.from    SMTP MAIL使用的Email地址,用来设置邮件的return地址。缺省是Message.getFrom()或InternetAddress.getLocalAddress()。注意:mail.smtp.user优先使用
mail.smtp.localhost    localhost名,缺省是 InetAddress.getLocalHost().getHostName()。如果JDK和name service正确配置,一般不需设置。
mail.host    邮件交互的主机。
mail.smtp.ehlo    如果为false,那么不会尝试使用EHLO命令登录,缺省是true。通常EHLO命令失败,会倒退到HELO命令。这个属性只有在服务器没有fail EHLO属性或没有实现EHLO属性。
mail.user    登录邮件服务器的用户名(发送邮件时需要)。
mail.from    发件人地址(发送邮件时需要)。

SMTP协议支持的所有属性:

Name    Type    Description
mail.smtp.user    String    Default user name for SMTP.
mail.smtp.host    String    The SMTP server to connect to.
mail.smtp.port    int    The SMTP server port to connect to, if the connect() method doesn’t explicitly specify one. Defaults to 25.
mail.smtp.connectiontimeout    int    Socket connection timeout value in milliseconds. This timeout is implemented by java.net.Socket. Default is infinite timeout.
mail.smtp.timeout    int    Socket read timeout value in milliseconds. This timeout is implemented by java.net.Socket. Default is infinite timeout.
mail.smtp.writetimeout    int    Socket write timeout value in milliseconds. This timeout is implemented by using a java.util.concurrent.ScheduledExecutorService per connection that schedules a thread to close the socket if the timeout expires. Thus, the overhead of using this timeout is one thread per connection. Default is infinite timeout.
mail.smtp.from    String    Email address to use for SMTP MAIL command. This sets the envelope return address. Defaults to msg.getFrom() or InternetAddress.getLocalAddress(). NOTE: mail.smtp.user was previously used for this.
mail.smtp.localhost    String    Local host name used in the SMTP HELO or EHLO command. Defaults to InetAddress.getLocalHost().getHostName(). Should not normally need to be set if your JDK and your name service are configured properly.
mail.smtp.localaddress    String    Local address (host name) to bind to when creating the SMTP socket. Defaults to the address picked by the Socket class. Should not normally need to be set, but useful with multi-homed hosts where it’s important to pick a particular local address to bind to.
mail.smtp.localport    int    Local port number to bind to when creating the SMTP socket. Defaults to the port number picked by the Socket class.
mail.smtp.ehlo    boolean    If false, do not attempt to sign on with the EHLO command. Defaults to true. Normally failure of the EHLO command will fallback to the HELO command; this property exists only for servers that don’t fail EHLO properly or don’t implement EHLO properly.
mail.smtp.auth    boolean    If true, attempt to authenticate the user using the AUTH command. Defaults to false.
mail.smtp.auth.mechanisms    String    If set, lists the authentication mechanisms to consider, and the order in which to consider them. Only mechanisms supported by the server and supported by the current implementation will be used. The default is “LOGIN PLAIN DIGEST-MD5 NTLM”, which includes all the authentication mechanisms supported by the current implementation except XOAUTH2.
mail.smtp.auth.login.disable    boolean    If true, prevents use of the AUTH LOGIN command. Default is false.
mail.smtp.auth.plain.disable    boolean    If true, prevents use of the AUTH PLAIN command. Default is false.
mail.smtp.auth.digest-md5.disable    boolean    If true, prevents use of the AUTH DIGEST-MD5 command. Default is false.
mail.smtp.auth.ntlm.disable    boolean    If true, prevents use of the AUTH NTLM command. Default is false.
mail.smtp.auth.ntlm.domain    String    The NTLM authentication domain.
mail.smtp.auth.ntlm.flags    int    NTLM protocol-specific flags. See http://curl.haxx.se/rfc/ntlm.html#theNtlmFlags for details.
mail.smtp.auth.xoauth2.disable    boolean    If true, prevents use of the AUTHENTICATE XOAUTH2 command. Because the OAuth 2.0 protocol requires a special access token instead of a password, this mechanism is disabled by default. Enable it by explicitly setting this property to “false” or by setting the “mail.smtp.auth.mechanisms” property to “XOAUTH2”.
mail.smtp.submitter    String    The submitter to use in the AUTH tag in the MAIL FROM command. Typically used by a mail relay to pass along information about the original submitter of the message. See also the setSubmittermethod of SMTPMessage. Mail clients typically do not use this.
mail.smtp.dsn.notify    String    The NOTIFY option to the RCPT command. Either NEVER, or some combination of SUCCESS, FAILURE, and DELAY (separated by commas).
mail.smtp.dsn.ret    String    The RET option to the MAIL command. Either FULL or HDRS.
mail.smtp.allow8bitmime    boolean    If set to true, and the server supports the 8BITMIME extension, text parts of messages that use the “quoted-printable” or “base64” encodings are converted to use “8bit” encoding if they follow the RFC2045 rules for 8bit text.
mail.smtp.sendpartial    boolean    If set to true, and a message has some valid and some invalid addresses, send the message anyway, reporting the partial failure with a SendFailedException. If set to false (the default), the message is not sent to any of the recipients if there is an invalid recipient address.
mail.smtp.sasl.enable    boolean    If set to true, attempt to use the javax.security.sasl package to choose an authentication mechanism for login. Defaults to false.
mail.smtp.sasl.mechanisms    String    A space or comma separated list of SASL mechanism names to try to use.
mail.smtp.sasl.authorizationid    String    The authorization ID to use in the SASL authentication. If not set, the authentication ID (user name) is used.
mail.smtp.sasl.realm    String    The realm to use with DIGEST-MD5 authentication.
mail.smtp.sasl.usecanonicalhostname    boolean    If set to true, the canonical host name returned by InetAddress.getCanonicalHostName is passed to the SASL mechanism, instead of the host name used to connect. Defaults to false.
mail.smtp.quitwait    boolean    If set to false, the QUIT command is sent and the connection is immediately closed. If set to true (the default), causes the transport to wait for the response to the QUIT command.
mail.smtp.reportsuccess    boolean    If set to true, causes the transport to include an SMTPAddressSucceededException for each address that is successful. Note also that this will cause a SendFailedException to be thrown from thesendMessage method of SMTPTransport even if all addresses were correct and the message was sent successfully.
mail.smtp.socketFactory    SocketFactory    If set to a class that implements the javax.net.SocketFactory interface, this class will be used to create SMTP sockets. Note that this is an instance of a class, not a name, and must be set using the putmethod, not the setProperty method.
mail.smtp.socketFactory.class    String    If set, specifies the name of a class that implements the javax.net.SocketFactory interface. This class will be used to create SMTP sockets.
mail.smtp.socketFactory.fallback    boolean    If set to true, failure to create a socket using the specified socket factory class will cause the socket to be created using the java.net.Socket class. Defaults to true.
mail.smtp.socketFactory.port    int    Specifies the port to connect to when using the specified socket factory. If not set, the default port will be used.
mail.smtp.ssl.enable    boolean    If set to true, use SSL to connect and use the SSL port by default. Defaults to false for the “smtp” protocol and true for the “smtps” protocol.
mail.smtp.ssl.checkserveridentity    boolean    If set to true, check the server identity as specified by RFC 2595. These additional checks based on the content of the server’s certificate are intended to prevent man-in-the-middle attacks. Defaults to false.
mail.smtp.ssl.trust    String    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.
mail.smtp.ssl.socketFactory    SSLSocketFactory    If set to a class that extends the javax.net.ssl.SSLSocketFactory class, this class will be used to create SMTP SSL sockets. Note that this is an instance of a class, not a name, and must be set using theput method, not the setProperty method.
mail.smtp.ssl.socketFactory.class    String    If set, specifies the name of a class that extends the javax.net.ssl.SSLSocketFactory class. This class will be used to create SMTP SSL sockets.
mail.smtp.ssl.socketFactory.port    int    Specifies the port to connect to when using the specified socket factory. If not set, the default port will be used.
mail.smtp.ssl.protocols    string    Specifies the SSL protocols that will be enabled for SSL connections. The property value is a whitespace separated list of tokens acceptable to the javax.net.ssl.SSLSocket.setEnabledProtocolsmethod.
mail.smtp.ssl.ciphersuites    string    Specifies the SSL cipher suites that will be enabled for SSL connections. The property value is a whitespace separated list of tokens acceptable to the javax.net.ssl.SSLSocket.setEnabledCipherSuitesmethod.
mail.smtp.starttls.enable    boolean    If true, enables the use of the STARTTLS command (if supported by the server) to switch the connection to a TLS-protected connection before issuing any login commands. Note that an appropriate trust store must configured so that the client will trust the server’s certificate. Defaults to false.
mail.smtp.starttls.required    boolean    If true, requires the use of the STARTTLS command. If the server doesn’t support the STARTTLS command, or the command fails, the connect method will fail. Defaults to false.
mail.smtp.socks.host    string    Specifies the host name of a SOCKS5 proxy server that will be used for connections to the mail server. (Note that this only works on JDK 1.5 or newer.)
mail.smtp.socks.port    string    Specifies the port number for the SOCKS5 proxy server. This should only need to be used if the proxy server is not using the standard port number of 1080.
mail.smtp.mailextension    String    Extension string to append to the MAIL command. The extension string can be used to specify standard SMTP service extensions as well as vendor-specific extensions. Typically the application should use the SMTPTransport method supportsExtension to verify that the server supports the desired service extension. See RFC 1869 and other RFCs that define specific extensions.
mail.smtp.userset    boolean    If set to true, use the RSET command instead of the NOOP command in the isConnected method. In some cases sendmail will respond slowly after many NOOP commands; use of RSET avoids this sendmail issue. Defaults to false.
mail.smtp.noop.strict    boolean    If set to true (the default), insist on a 250 response code from the NOOP command to indicate success. The NOOP command is used by the isConnected method to determine if the connection is still alive. Some older servers return the wrong response code on success, some servers don’t implement the NOOP command at all and so always return a failure code. Set this property to false to handle servers that are broken in this way. Normally, when a server times out a connection, it will send a 421 response code, which the client will see as the response to the next command it issues. Some servers send the wrong failure response code when timing out a connection. Do not set this property to false when dealing with servers that are broken in this way.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值