一、邮件的概念
- javamail主要包括两部分:生成邮件和发送接收邮件
二、邮件中使用的协议(SMTP协议、POP协议、MIME协议、RFC822规范)
- SMTP协议:Simple Message Transfer Protocal 简单邮件的传输协议(发送邮件时使用),默认的端口是:25
- POP3协议:Post Office Protocol 邮局协议,(接收邮件时使用),默认的端口是:110
三、手工接收和发送邮件(telnet 命令)
- 自己给自己发:itheimastudy@163.com 1233211234567
- SMTP协议详解
- SMTP协议详解:
- telnet smtp.163.com 25 //链接163的邮件发送服务器
- //以下是SMPT协议规定的
- ehlo itheima //向服务器打招呼
- auth login //请求认证:用户名和密码都必须用Base64进行编码
- aXRoZWltYXN0dWR5 //用户名
- MTIzMzIxMTIzNDU2Nw== //密码
- mail from:<itheimastudy@163.com> //发件人
- rcpt to:<itheimastudy@163.com> //收件人
- data //证明邮件的开始
- from:fengjie@163.com //发件人
- to:itheimastudy@163.com //收件人 cc:抄送。bcc:密送。
- subject:ThisIsATest //主题
- ccccccccccccccccc
- ddddddddddddddddd
- . //正文结束标记
- quit
- RFC822规范
- SMTP没有看到邮件内容,它没有遵循邮件的格式。(RFC822规定了邮件的内容格式)
- RFC822规定了邮件由邮件头和邮件体组成,两者之间用一个空行分开
- ......
- data
- from:itheimastudy@163.com //发件人
- to:itheimastudy@163.com //收件人 cc:抄送。bcc:密送。
- subject ThisIsATest //主题
- ccccccccccccccccc
- ddddddddddddddddd
- .
- .......
- POP3接收邮件
- telnet pop.163.com 110
- //以下内容为POP协议规定的
- user itheimastudy
- pass 1233211234567
- stat //返回邮箱的统计信息
- list 邮箱编号 //从1开始
- retr 邮箱编号 //查看指定邮件的内容
四、冒充别人发送邮件
- main:
- Socket sock = new Socket("smtp.163.com",25); // smtp.163.com 连接服务器名和指定端口 25
- OutputStream out = sock.getOutputStream();
- InputStream in = sock.getInputStream();
- out.write("ehel aaa \r\n".getBytes()); //向服务器发送信息
- BufferedReader bufr = new BufferedReader(new FileInputStream(in));
- System.out.println(bufr.readline()); //读取服务器响应信息
- ......
- out.write("from:fengjie@qq.com".getBytes()); //可在此处修改发件人的信息
- out.write("to:zhouwanmou@qq.com".getBytes()); //正常发送邮件收件人
- ......
- sock.close();
五、如何创建邮件
- JavaMail:JavaEE技术的一种。邮件开发的规范(抽象类和接口)。
- 使用JavaMail开发,依赖JAF(Java Activation Framework)框架(JDK6-不含)。
- 1、只有文本内容的简单邮件
- Properties props = new Properties();
- Session session = Session.getDefaultInstance(props);
- MimeMessage mm = new MimeMessage(session);
- //设置发件人
- mm.setFrom(new InternetAddress("fengjie@163.com"));
- //设置收件人,to cc抄送 bcc密送
- mm.setRecipient(Message.RecipientType.TO, new InternetAddress("zhouwanmou@163.com"));
- mm.setSubject(“这是主题”); //设置主题
- mm.setText("hello fengjie");//设置邮件内容
- mm.saveChanges();//保存修改
- mm.writeTo(new FileOutputStream("d:/1.eml"));//邮件的扩展名为.eml 将邮件写到磁盘上
- ------------------------------------ -发送邮件 ---------------------------
- Properties props = new Properties();
- props.setProperty("mail.transport.protocol", "smtp");//key参考JavaMail的规范文档
- props.setProperty("mail.host", "smtp.163.com");
- props.setProperty("mail.smtp.auth", "true");//true此步骤请求身份验证
- Session session = Session.getDefaultInstance(props);
- session.setDebug(true);//打印信息到控制台
- //创建邮件
- MimeMessage mm = new MimeMessage(session);
- mm.setFrom(new InternetAddress("fengjie@163.com"));
- mm.setRecipient(Message.RecipientType.TO, new InternetAddress("zhouwanmou@163.com"));
- mm.setSubject("这是主题");//设置主题
- mm.setText("这是内容");
- mm.saveChanges();
- ----------------------
- //发送邮件步骤(方式1
- Transport send = session.getTransport();
- send.connect("用户名","密码");
- send.sendMessage(mm, mm.getAllRecipients());
- send.close();
- //发送邮件步骤(方式2
- //使用匿名内部类设置用户名密码,修改
- Session session = Session.getDefaultInstance(props,new Authenticator(){
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("用户名","密码");
- }
- });
- Transport.send(mm);
- 2、既有文本又有图片的邮件(MIME协议):有关系的related
- 每一部分内容:BodyPart MimeBodyPart
- 每部分内容的关系:Multipart MimeMultipart
- -----------------------3247892432
- Contety-Type:text/html;
- aaa<img src="cid:mm"/>bbb
- -----------------------3247892432
- Contety-Type:image/jpeg;
- Content-ID:mm
- lsjdflkdsjfdslk
- sdfldslkfdslkfd
- sdfldsfldslfkds
- -----------------------3247892432--
- ..............
- mm.setSubject("这是主题");
- //设置正文文本
- MimeBodyPart text = new MimeBodyPart();
- text.setContent("AAAAAAABB<img src='cid:mm'/>BBBBBBB", "text/html;charset=UTF-8");
- //设置正文图片
- MimeBodyPart image = new MimeBodyPart();
- DataHandler dh = new DataHandler(new FileDataSource("d:/1.jpg"));
- image.setDataHandler(dh);
- image.setContentID("mm");
- //建立文本和图片的关系
- MimeMultipart part = new MimeMultipart();
- part.addBodyPart(text);
- part.addBodyPart(image);
- part.setSubType("related");//设置关系
- mm.setContent(part);
- mm.saveChanges();//保存修改
- .............
- 3、既有文本又有图片还有附件的复杂邮件
- 在2的基础上再增加附件
- //附件部分MimeBodyPart attachment = new MimeBodyPart();dh = new DataHandler(new FileDataSource("c:/附件.zip"));String fileName = dh.getName();System.out.println(fileName);attachment.setDataHandler(dh);attachment.setFileName(MimeUtility.encodeText(fileName));//手工设置一下附件的文件名//把文本和图片搞成一个MimeBodyPart textImage = new MimeBodyPart();textImage.setContent(part);//进一步描述关系MimeMultipart mpart = new MimeMultipart();mpart.addBodyPart(textImage);mpart.addBodyPart(attachment);part.setSubType("mixed");//设置关系mm.setContent(mpart);
- 4、邮件中的中文问题
- 正文编码:text.setContent("大<img src='cid:mm'/>长腿", "text/html;charset=UTF-8");
- 附件中文名编码: attachment.setFileName(MimeUtility.encodeText(fileName));//手工设置一下附件的文件名
六、发送邮件:Javamail的API非常灵活
- 两种方式发送邮件见上
七、TomCat管理邮件中的Session遇到的诡异问题
- 拷贝mail的jar包到tomcat的lib中
- 在web应用的META-INFO下配置context.xml
-
< Context >< Resource name =" mail/Session " auth =" Container " type =" javax.mail.Session " mail.smtp.host =" smtp.163.com " /></ Context >
-
- 使用配置的session:
- public class SessionUtil {
- public static Session getSession(){
- try{
- Context initCtx = new InitialContext();
- Context envCtx = (Context) initCtx.lookup("java:comp/env");
- Session session = (Session) envCtx.lookup("mail/Session");
- return session;
- }catch(Exception e){
- throw new RuntimeException(e);
- }
- }
- }
- 出现的诡异问题分析:tomcat的类加载委托机制,出现session对象不能转成session对象的问题
- 解决方案:干掉其中一个jar包,删除应用lib中的jar包 或 在再次部署应用前 删除应用的lib中的jar包