樂樂隨筆

          綠葉

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            14 Posts :: 0 Stories :: 2 Comments :: 0 Trackbacks

          package org.vanvinfo.alarmManage.logic.alarmReceiver;

          import java.io.BufferedReader;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileNotFoundException;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InputStreamReader;
          import java.io.PrintWriter;
          import java.io.UnsupportedEncodingException;
          import java.net.Socket;
          import java.nio.charset.Charset;
          import java.text.SimpleDateFormat;
          import java.util.ArrayList;
          import java.util.Date;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;

          import sun.misc.BASE64Encoder;

          /**
           * 該類使用Socket連接到郵件服務(wù)器,
           * 并實現(xiàn)了向指定郵箱發(fā)送郵件及附件的功能。
           *
           * @author Zhong Lizhi
           */
          public class Mail {
             
              /**
               * 換行符
               */
              private static final String LINE_END = "\r\n";
             
              /**
               * 值為“true”輸出高度信息(包括服務(wù)器響應(yīng)信息),值為“
               * false”則不輸出調(diào)試信息。
               */
              private boolean isDebug = true;
             
              /**
               * 值為“true”則在發(fā)送郵件{@link Mail#send()}
               * 過程中會讀取服務(wù)器端返回的消息,
               * 并在郵件發(fā)送完畢后將這些消息返回給用戶。
               */
              private boolean isAllowReadSocketInfo = true;
             
              /**
               * 郵件服務(wù)器地址
               */
              private String host;
             
              /**
               * 發(fā)件人郵箱地址
               */
              private String from;
             
              /**
               * 收件人郵箱地址
               */
              private List<String> to;
             
              /**
               * 抄送地址
               */
              private List<String> cc;
             
              /**
               * 暗送地址
               */
              private List<String> bcc;
             
              /**
               * 郵件主題
               */
              private String subject;
             
              /**
               * 用戶名
               */
              private String user;
             
              /**
               * 密碼
               */
              private String password;
             
              /**
               * MIME郵件類型
               */
              private String contentType;
             
              /**
               * 用來綁定多個郵件單元{@link #partSet}
               * 的分隔標識,我們可以將郵件的正文及每一個附件都看作是一個郵件單元
               * 。
               */
              private String boundary;
             
              /**
               * 郵件單元分隔標識符,該屬性將用來在郵件中作為分割各個郵件單元的標識
               * 。
               */
              private String boundaryNextPart;
             
              /**
               * 傳輸郵件所采用的編碼
               */
              private String contentTransferEncoding;
             
              /**
               * 設(shè)置郵件正文所用的字符集
               */
              private String charset;
             
              /**
               * 內(nèi)容描述
               */
              private String contentDisposition;
             
              /**
               * 郵件正文
               */
              private String content;
             
              /**
               * 發(fā)送郵件日期的顯示格式
               */
              private String simpleDatePattern;
             
              /**
               * 附件的默認MIME類型
               */
              private String defaultAttachmentContentType;
             
              /**
               * 郵件單元的集合,用來存放正文單元和所有的附件單元。
               */
              private List<MailPart> partSet;
             
              /**
               * 不同類型文件對應(yīng)的{@link MIME} 類型映射。在添加附件
               * {@link #addAttachment(String)}
               * 時,程序會在這個映射中查找對應(yīng)文件的 {@link MIME}
               * 類型,如果沒有, 則使用
               * {@link #defaultAttachmentContentType}
               * 所定義的類型。
               */
              private static Map<String, String> contentTypeMap;
             
              static {
                  // MIME Media Types
                  contentTypeMap = new HashMap<String, String>();
                  contentTypeMap.put("xls", "application/vnd.ms-excel");
                  contentTypeMap.put("xlsx", "application/vnd.ms-excel");
                  contentTypeMap.put("xlsm", "application/vnd.ms-excel");
                  contentTypeMap.put("xlsb", "application/vnd.ms-excel");
                  contentTypeMap.put("doc", "application/msword");
                  contentTypeMap.put("dot", "application/msword");
                  contentTypeMap.put("docx", "application/msword");
                  contentTypeMap.put("docm", "application/msword");
                  contentTypeMap.put("dotm", "application/msword");
              }
             
              /**
               * 該類用來實例化一個正文單元或附件單元對象,他繼承了
               * {@link Mail}
               * ,在這里制作這個子類主要是為了區(qū)別郵件單元對象和郵件服務(wù)對象
               * ,使程序易讀一些。 這些郵件單元全部會放到partSet
               * 中,在發(fā)送郵件 {@link #send()}時, 程序會調(diào)用
               * {@link #getAllParts()}
               * 方法將所有的單元合并成一個符合MIME格式的字符串。
               *
               * @author Zhong Lizhi
               */
              private class MailPart extends Mail {
                  public MailPart() {
                  }
              }
             
              /**
               * 默認構(gòu)造函數(shù)
               */
              public Mail() {
                  defaultAttachmentContentType = "application/octet-stream";
                  simpleDatePattern = "yyyy-MM-dd HH:mm:ss";
                  boundary = "--=_NextPart_zlz_3907_" + System.currentTimeMillis();
                  boundaryNextPart = "--" + boundary;
                  contentTransferEncoding = "base64";
                  contentType = "multipart/alternative";
                  charset = Charset.defaultCharset().name();
                  partSet = new ArrayList<MailPart>();
                  to = new ArrayList<String>();
                  cc = new ArrayList<String>();
                  bcc = new ArrayList<String>();
              }
             
              /**
               * 根據(jù)指定的完整文件名在
               * {@link #contentTypeMap}
               * 中查找其相應(yīng)的MIME類型, 如果沒找到,則返回
               * {@link #defaultAttachmentContentType}
               * 所指定的默認類型。
               *
               * @param fileName
               *            文件名
               * @return 返回文件對應(yīng)的MIME類型。
               */
              private String getPartContentType(String fileName) {
                  String ret = null;
                  if (null != fileName) {
                      int flag = fileName.lastIndexOf(".");
                      if (0 <= flag && flag < fileName.length() - 1) {
                          fileName = fileName.substring(flag + 1);
                      }
                      ret = contentTypeMap.get(fileName);
                  }
                 
                  if (null == ret) {
                      ret = defaultAttachmentContentType;
                  }
                  return ret;
              }
             
              /**
               * 將給定字符串轉(zhuǎn)換為base64編碼的字符串
               *
               * @param str
               *            需要轉(zhuǎn)碼的字符串
               * @param charset
               *            原字符串的編碼格式
               * @return base64編碼格式的字符
               */
              private String toBase64(String str, String charset) {
                  if (null != str) {
                      try {
                          return toBase64(str.getBytes(charset));
                      } catch (UnsupportedEncodingException e) {
                          e.printStackTrace();
                      }
                  }
                  return "";
              }
             
              /**
               * 將指定的字節(jié)數(shù)組轉(zhuǎn)換為base64格式的字符串
               *
               * @param bs
               *            需要轉(zhuǎn)碼的字節(jié)數(shù)組
               * @return base64編碼格式的字符
               */
              private String toBase64(byte[] bs) {
                  return new BASE64Encoder().encode(bs);
              }
             
              /**
               * 將給定字符串轉(zhuǎn)換為base64編碼的字符串
               *
               * @param str
               *            需要轉(zhuǎn)碼的字符串
               * @return base64編碼格式的字符
               */
              private String toBase64(String str) {
                  return toBase64(str, Charset.defaultCharset().name());
              }
             
              /**
               * 將所有的郵件單元按照標準的MIME格式要求合并。
               *
               * @return 返回一個所有單元合并后的字符串。
               */
              private String getAllParts() {
                  int partCount = partSet.size();
                  StringBuilder sbd = new StringBuilder(LINE_END);
                  for (int i = partCount - 1; i >= 0; i--) {
                      Mail attachment = partSet.get(i);
                      String attachmentContent = attachment.getContent();
                      if (null != attachmentContent && 0 < attachmentContent.length()) {
                          sbd.append(getBoundaryNextPart()).append(LINE_END);
                          sbd.append("Content-Type: ");
                          sbd.append(attachment.getContentType());
                          sbd.append(LINE_END);
                          sbd.append("Content-Transfer-Encoding: ");
                          sbd.append(attachment.getContentTransferEncoding());
                          sbd.append(LINE_END);
                          if (i != partCount - 1) {
                              sbd.append("Content-Disposition: ");
                              sbd.append(attachment.getContentDisposition());
                              sbd.append(LINE_END);
                          }
                         
                          sbd.append(LINE_END);
                          sbd.append(attachment.getContent());
                          sbd.append(LINE_END);
                      }
                  }
                 
                  sbd.append(LINE_END);
                  sbd.append(LINE_END);
                  // sbd.append(boundaryNextPart).
                  // append(LINE_END);
                  partSet.clear();
                  return sbd.toString();
              }
             
              /**
               * 添加郵件正文單元
               */
              private void addContent() {
                  if (null != content) {
                      MailPart part = new MailPart();
                      part.setContent(toBase64(content));
                      part.setContentType("text/plain;charset=\"" + charset + "\"");
                      partSet.add(part);
                  }
              }
             
              private String listToMailString(List<String> mailAddressList) {
                  StringBuilder sbd = new StringBuilder();
                  if (null != mailAddressList) {
                      int listSize = mailAddressList.size();
                      for (int i = 0; i < listSize; i++) {
                          if (0 != i) {
                              sbd.append(";");
                          }
                          sbd.append("<").append(mailAddressList.get(i)).append(">");
                      }
                  }
                  return sbd.toString();
              }
             
              private List<String> getrecipient() {
                  List<String> list = new ArrayList<String>();
                  list.addAll(to);
                  list.addAll(cc);
                  list.addAll(bcc);
                  return list;
              }
             
              /**
               * 添加一個附件單元
               *
               * @param filePath
               *            文件路徑
               */
              public void addAttachment(String filePath) {
                  addAttachment(filePath, null);
              }
             
              public void addTo(String mailAddress) {
                  this.to.add(mailAddress);
              }
             
              public void addCc(String mailAddress) {
                  this.cc.add(mailAddress);
              }
             
              public void addBcc(String mailAddress) {
                  this.bcc.add(mailAddress);
              }
             
              /**
               * 添加一個附件單元
               *
               * @param filePath
               *            文件路徑
               * @param charset
               *            文件編碼格式
               */
              public void addAttachment(String filePath, String charset) {
                  if (null != filePath && filePath.length() > 0) {
                      File file = new File(filePath);
                      try {
                          addAttachment(file.getName(), new FileInputStream(file),
                                  charset);
                      } catch (FileNotFoundException e) {
                          System.out.println("錯誤:" + e.getMessage());
                          System.exit(1);
                      }
                  }
              }
             
              /**
               * 添加一個附件單元
               *
               * @param fileName
               *            文件名
               * @param attachmentStream
               *            文件流
               * @param charset
               *            文件編碼格式
               */
              public void addAttachment(String fileName, InputStream attachmentStream,
                      String charset) {
                  try {
                     
                      byte[] bs = null;
                      if (null != attachmentStream) {
                          int buffSize = 1024;
                          byte[] buff = new byte[buffSize];
                          byte[] temp;
                          bs = new byte[0];
                          int readTotal = 0;
                          while (-1 != (readTotal = attachmentStream.read(buff))) {
                              temp = new byte[bs.length];
                              System.arraycopy(bs, 0, temp, 0, bs.length);
                              bs = new byte[temp.length + readTotal];
                              System.arraycopy(temp, 0, bs, 0, temp.length);
                              System.arraycopy(buff, 0, bs, temp.length, readTotal);
                          }
                      }
                     
                      if (null != bs) {
                          MailPart attachmentPart = new MailPart();
                          charset = null != charset ? charset : Charset.defaultCharset()
                                  .name();
                          String contentType = getPartContentType(fileName)
                                  + ";name=\"=?" + charset + "?B?" + toBase64(fileName)
                                  + "?=\"";
                          attachmentPart.setCharset(charset);
                          attachmentPart.setContentType(contentType);
                          attachmentPart.setContentDisposition("attachment;filename=\"=?"
                                  + charset + "?B?" + toBase64(fileName) + "?=\"");
                          attachmentPart.setContent(toBase64(bs));
                          partSet.add(attachmentPart);
                      }
                     
                  } catch (Exception e) {
                      e.printStackTrace();
                  } finally {
                      if (null != attachmentStream) {
                          try {
                              attachmentStream.close();
                              attachmentStream = null;
                          } catch (IOException e) {
                              e.printStackTrace();
                          }
                      }
                     
                      Runtime.getRuntime().gc();
                      Runtime.getRuntime().runFinalization();
                  }
              }
             
              /**
               * 發(fā)送郵件
               *
               * @return 郵件服務(wù)器反回的信息
               */
              public String send() {
                 
                  // 對象申明
                  // 當郵件發(fā)送完畢后,以下三個對象(Socket、
                  // PrintWriter,
                  // BufferedReader)需要關(guān)閉。
                  Socket socket = null;
                  PrintWriter pw = null;
                  BufferedReader br = null;
                 
                  try {
                      socket = new Socket(host, 25);
                      pw = new PrintWriter(socket.getOutputStream());
                      br = new BufferedReader(new InputStreamReader(socket
                              .getInputStream()));
                     
                      StringBuilder infoBuilder = new StringBuilder(
                              "\nServer info: \n------------\n");
                     
                      // 與服務(wù)器建立連接
                      pw.write("HELO ".concat(host).concat(LINE_END)); // 連接到郵件服務(wù)
                      if (!readResponse(pw, br, infoBuilder, "220"))
                          return infoBuilder.toString();
                     
                      pw.write("AUTH LOGIN".concat(LINE_END)); // 登錄
                      if (!readResponse(pw, br, infoBuilder, "250"))
                          return infoBuilder.toString();
                     
                      pw.write(toBase64(user).concat(LINE_END)); // 輸入用戶名
                      if (!readResponse(pw, br, infoBuilder, "334"))
                          return infoBuilder.toString();
                     
                      pw.write(toBase64(password).concat(LINE_END)); // 輸入密碼
                      if (!readResponse(pw, br, infoBuilder, "334"))
                          return infoBuilder.toString();
                     
                      pw.write("MAIL FROM:<" + from + ">" + LINE_END); // 發(fā)件人郵箱地址
                      if (!readResponse(pw, br, infoBuilder, "235"))
                          return infoBuilder.toString();
                     
                      List<String> recipientList = getrecipient();
                      // 收件郵箱地址
                      for (int i = 0; i < recipientList.size(); i++) {
                          pw.write("RCPT TO:<" + recipientList.get(i) + ">" + LINE_END);
                          if (!readResponse(pw, br, infoBuilder, "250"))
                              return infoBuilder.toString();
                      }
                      // System.out.println(
                      // getAllSendAddress());
                     
                      pw.write("DATA" + LINE_END); // 開始輸入郵件
                      if (!readResponse(pw, br, infoBuilder, "250"))
                          return infoBuilder.toString();
                     
                      flush(pw);
                     
                      // 設(shè)置郵件頭信息
                      StringBuffer sbf = new StringBuffer("From: <" + from + ">"
                              + LINE_END); // 發(fā)件人
                      sbf.append("To: " + listToMailString(to) + LINE_END);// 收件人
                      sbf.append("Cc: " + listToMailString(cc) + LINE_END);// 收件人
                      sbf.append("Bcc: " + listToMailString(bcc) + LINE_END);// 收件人
                      sbf.append("Subject: " + subject + LINE_END);// 郵件主題
                      SimpleDateFormat sdf = new SimpleDateFormat(simpleDatePattern);
                      sbf.append("Date: ").append(sdf.format(new Date()));
                      sbf.append(LINE_END); // 發(fā)送時間
                      sbf.append("Content-Type: ");
                      sbf.append(contentType);
                      sbf.append(";");
                      sbf.append("boundary=\"");
                      sbf.append(boundary).append("\""); // 郵件類型設(shè)置
                      sbf.append(LINE_END);
                      sbf.append("This is a multi-part message in MIME format.");
                      sbf.append(LINE_END);
                     
                      // 添加郵件正文單元
                      addContent();
                     
                      // 合并所有單元,正文和附件。
                      sbf.append(getAllParts());
                     
                      // 發(fā)送
                      sbf.append(LINE_END).append(".").append(LINE_END);
                      pw.write(sbf.toString());
                      readResponse(pw, br, infoBuilder, "354");
                      flush(pw);
                     
                      // QUIT退出
                      pw.write("QUIT" + LINE_END);
                      if (!readResponse(pw, br, infoBuilder, "250"))
                          return infoBuilder.toString();
                      flush(pw);
                     
                      return infoBuilder.toString();
                  } catch (Exception e) {
                      e.printStackTrace();
                      return "Exception:>" + e.getMessage();
                  } finally {
                      // 釋放資源
                      try {
                          if (null != socket)
                              socket.close();
                          if (null != pw)
                              pw.close();
                          if (null != br)
                              br.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                     
                      // this.to.clear();
                      // this.cc.clear();
                      // this.bcc.clear();
                      this.partSet.clear();
                  }
                 
              }
             
              /**
               * 將SMTP命令發(fā)送到郵件服務(wù)器
               *
               * @param pw
               *            郵件服務(wù)器輸入流
               */
              private void flush(PrintWriter pw) {
                  if (!isAllowReadSocketInfo) {
                      pw.flush();
                  }
              }
             
              /**
               * 讀取郵件服務(wù)器的響應(yīng)信息
               *
               * @param pw
               *            郵件服務(wù)器輸入流
               * @param br
               *            郵件服務(wù)器輸出流
               * @param infoBuilder
               *            用來存放服務(wù)器響應(yīng)信息的字符串緩沖
               * @param msgCode
               * @return
               * @throws IOException
               */
              private boolean readResponse(PrintWriter pw, BufferedReader br,
                      StringBuilder infoBuilder, String msgCode) throws IOException {
                  if (isAllowReadSocketInfo) {
                      pw.flush();
                      String message = br.readLine();
                      infoBuilder.append("SERVER:/>");
                      infoBuilder.append(message).append(LINE_END);
                      if (null == message || 0 > message.indexOf(msgCode)) {
                          System.out.println("ERROR: " + message);
                          pw.write("QUIT".concat(LINE_END));
                          pw.flush();
                          return false;
                      }
                      if (isDebug) {
                          System.out.println("DEBUG:/>" + msgCode + "/" + message);
                      }
                  }
                  return true;
              }
             
              public String getBoundaryNextPart() {
                  return boundaryNextPart;
              }
             
              public void setBoundaryNextPart(String boundaryNextPart) {
                  this.boundaryNextPart = boundaryNextPart;
              }
             
              public String getDefaultAttachmentContentType() {
                  return defaultAttachmentContentType;
              }
             
              public void setDefaultAttachmentContentType(
                      String defaultAttachmentContentType) {
                  this.defaultAttachmentContentType = defaultAttachmentContentType;
              }
             
              public String getHost() {
                  return host;
              }
             
              public void setHost(String host) {
                  this.host = host;
              }
             
              public String getFrom() {
                  return from;
              }
             
              public void setFrom(String from) {
                  this.from = from;
              }
             
              public List<String> getTo() {
                  return to;
              }
             
              public void setTo(List<String> to) {
                  this.to = to;
              }
             
              public String getSubject() {
                  return subject;
              }
             
              public void setSubject(String subject) {
                  this.subject = subject;
              }
             
              public String getUser() {
                  return user;
              }
             
              public void setUser(String user) {
                  this.user = user;
              }
             
              public String getPassword() {
                  return password;
              }
             
              public void setPassword(String password) {
                  this.password = password;
              }
             
              public String getContentType() {
                  return contentType;
              }
             
              public void setContentType(String contentType) {
                  this.contentType = contentType;
              }
             
              public String getBoundary() {
                  return boundary;
              }
             
              public void setBoundary(String boundary) {
                  this.boundary = boundary;
              }
             
              public String getContentTransferEncoding() {
                  return contentTransferEncoding;
              }
             
              public void setContentTransferEncoding(String contentTransferEncoding) {
                  this.contentTransferEncoding = contentTransferEncoding;
              }
             
              public String getCharset() {
                  return charset;
              }
             
              public void setCharset(String charset) {
                  this.charset = charset;
              }
             
              public String getContentDisposition() {
                  return contentDisposition;
              }
             
              public void setContentDisposition(String contentDisposition) {
                  this.contentDisposition = contentDisposition;
              }
             
              public String getSimpleDatePattern() {
                  return simpleDatePattern;
              }
             
              public void setSimpleDatePattern(String simpleDatePattern) {
                  this.simpleDatePattern = simpleDatePattern;
              }
             
              public String getContent() {
                  return content;
              }
             
              public void setContent(String content) {
                  this.content = content;
              }
             
              public boolean isAllowReadSocketInfo() {
                  return isAllowReadSocketInfo;
              }
             
              public void setAllowReadSocketInfo(boolean isAllowReadSocketInfo) {
                  this.isAllowReadSocketInfo = isAllowReadSocketInfo;
              }
             
              /**
               * @param args
               */
              public static void main(String[] args) {
                  // 應(yīng)用示例:線程化發(fā)送郵件
                  new Thread() {
                      @Override
                      public void run() {
                          System.out.println("SENDER-" + this.getId() + ":/>"
                                  + "開始發(fā)送郵件...");
                         
                          // 創(chuàng)建郵件對象
                          Mail mail = new Mail();
                          //http://oe.msn.msnmail.hotmail.com/cgi-bin/hmdata
                          mail.setHost("smtp.126.com"); // 郵件服務(wù)器地址
                          mail.setFrom("jiang_shi_jie@126.com"); // 發(fā)件人郵箱
                          mail.addTo("zhxtn@hotmail.com"); // 收件人郵箱
                          //mail.addCc("test@m1.com");
                          //mail.addBcc("test@m2.com");
                          mail.setSubject("CC Test Mail!!"); // 郵件主題
                          mail.setUser("jiang_shi_jie@126.com"); // 用戶名
                          mail.setPassword(""); // 密碼
                          mail.setContent("這是一個測試,請不要回復(fù)!"); // 郵件正文
                         
                          //mail.addAttachment("utf8中.txt"); // 添加附件
                          // mail.addAttachment(
                          // "e:/test.htm"); //
                          // 添加附件
                         
                          System.out.println(mail.send()); // 發(fā)送
                         
                          System.out.println("SENDER-" + this.getId() + ":/>"
                                  + "郵件已發(fā)送完畢!");
                      }
                  }.start();
                 
              }
             
          }


          //本文來自CSDN博客,轉(zhuǎn)載請標明出處:http://blog.csdn.net/zlz3907/archive/2009/03/04/3958081.aspx

          posted on 2010-02-05 17:25 綠葉 閱讀(543) 評論(0)  編輯  收藏 所屬分類: 技術(shù)總結(jié)
          主站蜘蛛池模板: 中超| 乌审旗| 怀宁县| 古蔺县| 尉氏县| 望奎县| 尼勒克县| 门源| 双流县| 怀远县| 北碚区| 永仁县| 土默特左旗| 莱州市| 天柱县| 宝兴县| 遵化市| 香河县| 门头沟区| 东辽县| 沽源县| 和田县| 邯郸县| 曲麻莱县| 镇安县| 泾阳县| 彝良县| 新宁县| 辽阳县| 黄龙县| 泰安市| 房产| 武定县| 保德县| 化州市| 琼结县| 新泰市| 井研县| 中宁县| 沽源县| 沁水县|