俊星的BLOG

          JAVAMAIL之我的SMTP客戶端實現

          JAVAMAIL源代碼中包含了對于SMTP發郵件的實現,下面是我的一個簡單實現:
          1、BASE64編碼類:
          package mymail;

          public class MyBase64Encoder {
              
          public static byte[] encode(byte[] inbuf) {
                  
          int size = inbuf.length;
                  
          byte[] outbuf = new byte[((size + 2/ 3* 4];
                  
          int inpos, outpos;
                  
          int val;
                  
          // 情況1:大于等于3
                  for (inpos = 0, outpos = 0; size >= 3; size -= 3, outpos += 4{
                      val 
          = inbuf[inpos++& 0xff;
                      val 
          <<= 8;
                      val 
          |= inbuf[inpos++& 0xff;
                      val 
          <<= 8;
                      val 
          |= inbuf[inpos++& 0xff;
                      
          // 到此val中存儲了3*8=24個二進制位,然后分4次,每次6個二進制位輸出
                      outbuf[outpos + 3= (byte) pem_array[val & 0x3f];
                      val 
          >>= 6;
                      outbuf[outpos 
          + 2= (byte) pem_array[val & 0x3f];
                      val 
          >>= 6;
                      outbuf[outpos 
          + 1= (byte) pem_array[val & 0x3f];
                      val 
          >>= 6;
                      outbuf[outpos 
          + 0= (byte) pem_array[val & 0x3f];
                  }

                  
          // 情況2:等于1或者等于2
                  if (size == 1{
                      val 
          = inbuf[inpos++& 0xff;
                      val 
          <<= 4;
                      
          // 到此val中實際有效二進制位8+4=12個,并且后4個都為0
                      outbuf[outpos + 3= (byte'='// pad character;
                      outbuf[outpos + 2= (byte'='// pad character;
                      outbuf[outpos + 1= (byte) pem_array[val & 0x3f];
                      val 
          >>= 6;
                      outbuf[outpos 
          + 0= (byte) pem_array[val & 0x3f];
                  }
           else if (size == 2{
                      val 
          = inbuf[inpos++& 0xff;
                      val 
          <<= 8;
                      val 
          |= inbuf[inpos++& 0xff;
                      val 
          <<= 2;
                      
          // 得到此val中實際有效二進制位為8+8+2=18個,并且后2個為0
                      outbuf[outpos + 3= (byte'='// pad character;
                      outbuf[outpos + 2= (byte) pem_array[val & 0x3f];
                      val 
          >>= 6;
                      outbuf[outpos 
          + 1= (byte) pem_array[val & 0x3f];
                      val 
          >>= 6;
                      outbuf[outpos 
          + 0= (byte) pem_array[val & 0x3f];
                  }

                  
          return outbuf;
              }


              
          private final static char pem_array[] = 'A''B''C''D''E''F''G''H'// 0
                      'I''J''K''L''M''N''O''P'// 1
                      'Q''R''S''T''U''V''W''X'// 2
                      'Y''Z''a''b''c''d''e''f'// 3
                      'g''h''i''j''k''l''m''n'// 4
                      'o''p''q''r''s''t''u''v'// 5
                      'w''x''y''z''0''1''2''3'// 6
                      '4''5''6''7''8''9''+''/' // 7
              }
          ;
          }


          2、具體應用類:
          package mymail;

          import java.io.File;
          import java.io.IOException;
          import java.util.Date;

          public class MyTest {
              
          public static void main(String[] args) throws IOException {
                  MyMsg msg 
          = new MyMsg();
                  msg.setSubject(
          "suject 主題");
                  msg.setFrom(
          "from@test.com");
                  msg.setRecipient(
          "test@test.com");
                  msg.setDate(
          new Date());

                  MyBodyPart body 
          = new MyBodyPart();
                  body.setText(
          "text 郵件正文");
                  MyBodyPart attach 
          = new MyBodyPart();
                  attach.attachFile(
          new File("D:\\My Documents\\music.txt"));

                  MyMultiPart content 
          = new MyMultiPart();
                  content.addPart(body);
                  content.addPart(attach);
                  msg.setContent(content);

                  SMTPTrans trans 
          = SMTPTrans.getInstance();
                  trans.setDebug(
          true);
                  trans.connect(
          "127.0.0.1");;
                  trans.sendMsg(msg);
              }

          }


          輸出:
          C:EHLO 127.0.0.1
          S:
          220 kinkding-d1d01d SMTP Server (JAMES SMTP Server 2.3.1) ready Sun, 26 Apr 2009 01:05:20 +0800 (CST)

          C:MAIL FROM:<from@test.com>
          S:
          250-kinkding-d1d01d Hello 127.0.0.1 (localhost [127.0.0.1])

          C:MAIL FROM:<from@test.com>
          S:
          250-PIPELINING

          C:RCPT TO:<test@test.com>
          S:
          250 ENHANCEDSTATUSCODES

          C:DATA
          S:
          250 2.1.0 Sender <from@test.com> OK

          C:.
          S:
          503 5.5.0 Sender already specified
          250 2.1.5 Recipient <test@test.com> OK
          354 Ok Send data ending with <CRLF>.<CRLF>

          C:QUIT
          S:
          250 2.6.0 Message received

          3、郵件類:
          package mymail;

          import java.io.IOException;
          import java.io.OutputStream;
          import java.text.SimpleDateFormat;
          import java.util.Date;
          import java.util.Locale;

          public class MyMsg {
              
          private String subject;
              
          private String from;
              
          private String recipient;
              
          private Date date;
              
          private String newline = "\r\n";
              
          private MyMultiPart content;

              
          public Date getDate() {
                  
          return date;
              }


              
          public void setDate(Date date) {
                  
          this.date = date;
              }


              
          public void setSubject(String subject) {
                  
          this.subject = subject;
              }


              
          public void setFrom(String from) {
                  
          this.from = from;
              }


              
          public String getRecipient() {
                  
          return recipient;
              }


              
          public void setRecipient(String recipient) {
                  
          this.recipient = recipient;
              }


              
          public String getSubject() {
                  
          return subject;
              }


              
          public String getFrom() {
                  
          return from;
              }

              
              
          public void setContent(MyMultiPart content) {
                  
          this.content = content;
              }


              
          public void writeTo(OutputStream out) throws IOException {
                  
          // 發送日期
                  SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss '+0800' (z)", Locale.US);
                  out.write((
          "Date: " + sdf.format(date) + newline).getBytes());
                  out.write((
          "From: " + this.from + newline).getBytes());
                  out.write((
          "To: " + this.recipient + newline).getBytes());
                  
          // 發送主題
                  out.write("Subject: =?gb2312?B?".getBytes());
                  out.write(MyBase64Encoder.encode(
          this.subject.getBytes()));
                  out.write((
          "?=" + newline).getBytes());
                  
          // 發送內容
                  this.content.writeTo(out);

              }


          }


          4、MyMultiPart:
          package mymail;

          import java.io.IOException;
          import java.io.OutputStream;
          import java.util.ArrayList;
          import java.util.List;

          public class MyMultiPart {
              
          private String boundary;
              
          private String contentType;
              
          private List<MyBodyPart> parts = new ArrayList<MyBodyPart>();
              
          private String newLine = "\r\n";

              
          public MyMultiPart() {
                  boundary 
          = "----=_Part_0" + this.hashCode() + "_" + System.currentTimeMillis();
                  contentType 
          = "Content-Type: multipart/mixed;";
              }


              
          public void addPart(MyBodyPart part) {
                  parts.add(part);
              }


              
          public void writeTo(OutputStream out) throws IOException {
                  out.write((
          this.contentType + "boundary=\"" + this.boundary+ "\"" + newLine).getBytes());
                  
          for (MyBodyPart body : parts) {
                      out.write((newLine
          +"--" + this.boundary + newLine).getBytes());
                      body.writeTo(out);
                      out.write(newLine.getBytes());
                      out.flush();
                  }

                  out.write((newLine
          +"--" + this.boundary + newLine).getBytes());
              }

          }


          5、MyBodyPart:
          package mymail;

          import java.io.File;
          import java.io.FileInputStream;
          import java.io.IOException;
          import java.io.OutputStream;

          public class MyBodyPart {
              
          private String contentType = "Content-Type: ";
              
          private String transferEncoding = "Content-Transfer-Encoding: base64";
              
          private String contentDisp;
              
          private String newLine = "\r\n";
              
          private String text;
              
          private File file;

              
          public void setText(String str) {
                  contentType 
          += "text/plain";
                  text 
          = str;
              }


              
          public void attachFile(File f) {
                  contentType 
          += "application/octet-stream; name=" + f.getName();
                  contentDisp 
          = "Content-Disposition: attachment; filename=" + f.getName();
                  file 
          = f;
              }


              
          public void writeTo(OutputStream out) throws IOException {
                  out.write((
          this.contentType + newLine).getBytes());
                  out.write((
          this.transferEncoding + newLine).getBytes());
                  
          if (this.text != null{
                      
          // 字符形式
                      out.write(newLine.getBytes());
                      
          this.byteWrite(out, text.getBytes());
                  }
           else {
                      
          // 文件形式
                      out.write((this.contentDisp + newLine + newLine).getBytes());
                      FileInputStream input 
          = new FileInputStream(file);
                      
          byte[] content = new byte[0];
                      
          byte[] buf = new byte[256];
                      
          int len;
                      
          while ((len = input.read(buf)) > -1{
                          
          byte[] temp = new byte[content.length];
                          System.arraycopy(content, 
          0, temp, 0, content.length);
                          content 
          = new byte[content.length + len];
                          System.arraycopy(temp, 
          0, content, 0, temp.length);
                          System.arraycopy(buf, 
          0, content, temp.length, len);
                      }

                      
          this.byteWrite(out, content);

                  }

              }


              
          private void byteWrite(OutputStream out, byte[] bytes) throws IOException {
                  
          byte[] encoded = MyBase64Encoder.encode(bytes);
                  
          // 每行最多76個字符輸出
                  int maxChar = 76;
                  
          int idx = 0;
                  
          for (int size = encoded.length / maxChar; idx < size; idx++{
                      out.write(encoded, idx 
          * maxChar, maxChar);
                      out.write(newLine.getBytes());
                  }

                  
          if (encoded.length % maxChar > 0{
                      out.write(encoded, idx 
          * maxChar, encoded.length % maxChar);
                      out.write(newLine.getBytes());
                  }

              }

          }


          6、查看生成的郵件:
          Return-Path: <from@test.com>
          Message
          -ID: <2737550.71240679122296.JavaMail.kinkding@kinkding-d1d01d>
          MIME
          -Version: 1.0
          Delivered
          -To: test@test.com
          Received: from localhost ([
          127.0.0.1])
                    by kinkding
          -d1d01d (JAMES SMTP Server 2.3.1) with SMTP ID 4
                    
          for <test@test.com>;
                    Sun, 
          26 Apr 2009 01:05:20 +0800 (CST)
          Date: Sun, 
          26 Apr 2009 01:05:20 +0800 (CST)
          From: from@test.com
          To: test@test.com
          Subject: 
          =?B?c3VqZWN0INb3zOI=?=
          Content
          -Type: multipart/mixed;boundary="----=_Part_010267414_1240679120062"

          ------=_Part_010267414_1240679120062
          Content
          -Type: text/plain
          Content
          -Transfer-Encoding: base64

          dGV4dCDTyrz
          +1f3OxA==


          ------=_Part_010267414_1240679120062
          Content
          -Type: application/octet-stream; name=music.txt
          Content
          -Transfer-Encoding: base64
          Content
          -Disposition: attachment; filename=music.txt

          MjAwOMTqtsi
          /4c7STtfaobDX7qGxDQoNCrCuyOfJ2cTqDQoNCg0KKy0tLS0tLS0tLS0tLS0tLS0t
          LS0tLS0tLS0tLS0tLS0tLS0rDQpNWVNRTDoNCrbLv9qjujMzMDYNClNlcnZlck5hbWU6TXlTUUwN
          CnJvb3Qvcm9vdA0KDQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsNCmRvbWFp
          bjoxMjcuMC4wLjENCnNlcnZlciBuYW1lOjEyNy4wLjAuMQ0KZW1haWw6dGVzdEB0ZXN0LmNvbQ0K
          DQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsNClVDZW50ZXI6dWNlbnRlcg0K
          ZGlzY3V6OmRpc2N1eg0KaHR0cDovL2xvY2FsaG9zdDo4MDcwL2Rpc2N1ei9pbmRleC5waHANCmh0
          dHA6Ly8xOTIuMTY4LjE4LjI6ODA3MC9kaXNjdXovaW5kZXgucGhw


          ------=_Part_010267414_1240679120062

          在FOXMAIL中查看郵件的截圖:


          7、點擊下載代碼

          posted on 2009-04-26 01:19 俊星 閱讀(1056) 評論(0)  編輯  收藏 所屬分類: 代碼庫

          主站蜘蛛池模板: 射阳县| 万年县| 巴东县| 阿巴嘎旗| 平安县| 安阳市| 普宁市| 客服| 苏尼特左旗| 湘乡市| 永福县| 长宁县| 遵义县| 山丹县| 宣化县| 金昌市| 凤冈县| 德钦县| 兴业县| 黄浦区| 闵行区| 禄丰县| 鹰潭市| 杭锦后旗| 银川市| 松江区| 绥德县| 齐齐哈尔市| 林芝县| 开原市| 华阴市| 建湖县| 沂水县| 台中县| 密山市| 凤台县| 双流县| 贵定县| 明星| 德令哈市| 循化|