话不多说 先上代码
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"); // 发送邮件的服务器地址
这样发送邮件的话 就可以直接发到自己设置的邮件服务器了
然后用本地邮箱打开就可以看到发出了邮件了