Jeff-亮

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

话不多说 先上代码

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;


public class TestMail2 {

    public static void main(String[] args) throws Exception {
        String email = "abc@163.com";// 收件人
        
        String emailMsg = "尊敬的客户:...";// 邮件正文内容
        String subject = "申请书"; 
        String bodyPartFlag = "true";
        String postType ="SendMsg";
        
        File attachment = new File("C:\\Users\\Administrator\\Desktop\\pdf\\test.pdf");
        if(!attachment.exists()){
            System.out.println("文件不存在");
        }
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(os);
        try {

            System.setProperty("mail.mime.splitlongparameters","false");
            Properties props = System.getProperties();
            props.setProperty("mail.transport.protocol", "SMTP");// 发邮件的协议
            // 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为:
            // smtp.xxx.com
            // 网易163邮箱的 SMTP 服务器地址为: smtp.163.com 腾讯: smtp.qq.com
            props.setProperty("mail.smtp.host", "smtp.qq.com"); // 发送邮件的服务器地址
            props.setProperty("mail.smtp.port", "25"); // 发送邮件的服务器地址
            // 需要请求认证
            props.setProperty("mail.smtp.auth", "true");// 指定验证为true
//            props.setProperty("proxySet", "true");
//            props.setProperty("http.proxyHost", "172.30.96.35");
//            props.setProperty("http.proxyPort", "8080");
//            props.setProperty("socksProxyHost", "172.30.96.35");
//            props.setProperty("socksProxyPort", "8080");
            // 创建验证器
            Authenticator auth = new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {

                    // 内网不通外网 需要打通网络关系

                    // 发件人的 邮箱 和 密码(替换为自己的邮箱和密码)
                    // 某些邮箱服务器为了增加邮箱本身密码的安全性,给 SMTP 客户端设置了独立密码(有的邮箱称为“授权码”),
                    // 对于开启了独立密码的邮箱, 这里的邮箱密码必需使用这个独立密码(授权码)
                    return new PasswordAuthentication("1111@qq.com", "1111");// 发邮件的账号的验证
                }
            };

            Session session = Session.getInstance(props, auth);
            System.out.println("JAVAMAIL debug mode is ON");
            session.setDebugOut(ps);
            session.setDebug(true); 
            // 2.创建一个Message,它相当于是邮件内容
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(
                    "\"" + MimeUtility.encodeText("111", "UTF-8", null) + "\" <490982493@qq.com>")); // 设置发送者
            // 发件人邮件
            // 得与上面的配置一致

            message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(email)); // 设置发送方式与接收者

            message.setSubject(MimeUtility.encodeText(subject, "UTF-8", null));// 设置主题
            // message.setText("这是一封激活邮件,请<a href='#'>点击</a>");
            // 设置邮件内容
            // 收件人email
            // 添加附件的内容
            // 向multipart对象中添加邮件的各个部分内容,包括文本内容和附件
            Multipart multipart = new MimeMultipart();
            BodyPart contentPart = new MimeBodyPart();
            contentPart.setContent(emailMsg, "text/html;charset=UTF-8");
            multipart.addBodyPart(contentPart);
            System.out.println("设置邮件内容为"+emailMsg);
            if (attachment != null&&"true".equals(bodyPartFlag)) {
                System.out.println("开始添加附件");
                BodyPart attachmentBodyPart = new MimeBodyPart();
                DataSource source = new FileDataSource(attachment);
                attachmentBodyPart.setDataHandler(new DataHandler(source));
                System.out.println("文件大小为:"+attachmentBodyPart.getDataHandler().toString());

                attachmentBodyPart.setFileName(MimeUtility.encodeWord("申请书.pdf", "UTF-8", null));
                System.out.println("文件名赋值成功");
                System.out.println("文件名:"+attachmentBodyPart.getFileName());
                multipart.addBodyPart(attachmentBodyPart);
                System.out.println("附件添加成功");
            }
            // 将multipart对象放到message中
                message.setContent(multipart);
                System.out.println("将multipart对象放到message中成功");
                // 保存邮件 
                message.saveChanges();
                System.out.println("保存邮件成功");
                System.out.println("发送前");
                System.out.println(os);
                if("SendMsg".equals(postType)){
                    Transport trans = session.getTransport("smtp");
                    // 链接邮件服务器
                    trans.connect("1111@qq.com", "1111");
                    // 发送信息
                    trans.sendMessage(message, message.getAllRecipients());
                    // 关闭链接
                    trans.close();
                }else{
                    // 3.创建 Transport用于将邮件发送
                    Transport.send(message);
                }
                System.out.println("发送邮件成功");
                System.out.println(os);
            } catch (Throwable e) {
                System.out.println("发送邮件出错了");
                System.out.println(os);
                System.out.println(e.getMessage());
                throw new  Exception("Validation.ra.error");
             }finally {
                  System.out.println("finally: "+os);    
                  ps.close();
                  try {
                    os.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
        System.out.println("发邮件成功");
    }

}

本来简单的已经成型一套发邮件代码 但由于网络问题没办法直接发到163或者qq邮箱测试 

没办法只能通过走代理

props.setProperty("proxySet", "true");
props.setProperty("http.proxyHost", "172.30.96.35");
props.setProperty("http.proxyPort", "8080");

一开始用这种http的代理模式发送 但试过发现这种方式行不通 邮件发不出去 报连接不到smtp的服务器

于是便换了一种方式

        props.setProperty("proxySet", "true");
        props.setProperty("socksProxyHost", "172.30.96.35");
        props.setProperty("socksProxyPort", "8080");

用socks协议的代理模式 

然而目前的的服务器不支持这种代理 所以此方法我也没办法验证正确性


 

这里注释一下 

System.out.println("JAVAMAIL debug mode is ON");
session.setDebugOut(ps);
session.setDebug(true); 

调试的时候可以把smtp的debug模式开启 更有助于分析问题


 

再之后 没办法只能转变思路 既然连不到外面的服务器 那我索性就自己整一个smtp的服务来测试就好

于是乎便找到了smtp4dev 一个简单的测试邮件的服务器 找不到资源的朋友可以私信我

 

点击Options 就可以配置自己的smtp服务的相关信息 

点击server 配置host 为localhost 和port为25 

然后在代码中将配置修改

props.setProperty("mail.smtp.host", "localhost"); // 发送邮件的服务器地址
props.setProperty("mail.smtp.port", "25"); // 发送邮件的服务器地址

这样发送邮件的话 就可以直接发到自己设置的邮件服务器了

 然后用本地邮箱打开就可以看到发出了邮件了


 

posted on 2021-07-07 09:28  Jeff-亮  阅读(142)  评论(0编辑  收藏  举报