春天花會開

          ***********

          統(tǒng)計

          留言簿(4)

          閱讀排行榜

          評論排行榜

          javamail讀取完整的郵件

          Javamail API雖然功能封裝的比較完整,但是要寫一個能正確顯示復雜郵件的程序還有很多邏輯和細節(jié)要處理。下面是我最近做一個webmail時整理的Servlet,基本上可以正確的讀取text,HTML,HTML中顯示圖片及附件。在本servlet中也簡單處理了常見的中文問題,包括主題、附件、HTML圖片中文、email Address中文??傮w感覺有兩個難點:1、附件和網頁圖片的抓取,需要定位數(shù)節(jié)點nodeid,光用partid是不行的;2、中文分兩種情況Base64和客戶端服務器端編碼不一致。本程序中實現(xiàn)了3種displayPart()的方法,具體情況不同結合使用效率更高。本程序還有一個未處理的地方就是我在做nodeid的時候最多算10個。當然還有其他問題歡迎指正,來出是為了給后來的初學者作個參考例子,少走彎路。
            1 import  java.io.IOException;
            2 import  java.io.InputStream;
            3 import  java.io.UnsupportedEncodingException;
            4 import  java.util.HashMap;
            5 import  javax.mail.Folder;
            6 import  javax.mail.Message;
            7 import  javax.mail.MessagingException;
            8 import  javax.mail.Multipart;
            9 import  javax.mail.Part;
           10 import  javax.mail.Store;
           11 import  javax.mail.internet.InternetAddress;
           12 import  javax.mail.internet.MimeUtility;
           13 import  javax.servlet.ServletException;
           14 import  javax.servlet.ServletOutputStream;
           15 import  javax.servlet.http.HttpServletRequest;
           16 import  javax.servlet.http.HttpServletResponse;
           17 import  javax.servlet.http.HttpSession;
           18 import  chunwei.mail.Login;
           19 import  chunwei.mail.MailUserData;
           20 /**
           21 * Servlet implementation class for Servlet: MailServlet
           22 * Author: luchunwei  Email: luchunwei@gmail.com
           23 */
           24 public  class MailNode extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
           25 private  static final long serialVersionUID = 1L;
           26 protected  void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           27 nodeid="";
           28 node="0";
           29 currentnodeid=0;
           30 url=request.getRequestURL().toString();
           31 HttpSession ses=request.getSession();
           32 MailUserData mud=(MailUserData)ses.getAttribute("mud");
           33 ServletOutputStream out=response.getOutputStream();
           34 response.setContentType("text/html;charset=GB2312");
           35 int  msgid=-1,partid=-1;//msgdi:郵件編號;partid:MultiPart Message中part的編號。
           36 String  partname=null//圖片或附件的文件名
           37 String  nodepara=null;//節(jié)點編號,如1-2-1-0, 他以便層層剝入
           38 if (request.getParameter("msgid")!=null)
           39 msgid=Integer.parseInt(request.getParameter("msgid"));
           40 msgidStr="msgid="+msgid;
           41 if (request.getParameter("partid")!=null)
           42 partid=Integer.parseInt(request.getParameter("partid"));
           43 if (request.getParameter("partname")!=null)
           44 partname=new String(request.getParameter("partname").getBytes("ISO-8859-1"),"GB2312");
           45 if (request.getParameter("node")!=null)
           46 nodepara=request.getParameter("node");
           47 System.out.println(nodepara);
           48 //System.out.println(msgid+":"+partid+":"+partname);
           49 if (partname!=null){
           50 //displayImages
           51 try  {
           52 displayPart(partname,response,out);
           53 }  catch (MessagingException e) {
           54 e.printStackTrace();
           55 }  catch (IOException e) {
           56 e.printStackTrace();
           57 }
           58 return;
           59 }
           60 //--------------------------
           61 if (mud==null){
           62 Login login=new Login("imap","mail.server.com",-1,"user","password");
           63 login.login();
           64 if (login.getResult()==1){
           65 HttpSession session = request.getSession();
           66 session.setMaxInactiveInterval(3600);
           67 session.setAttribute("mud",login.getMud());
           68 }
           69 mud=(MailUserData)ses.getAttribute("mud");
           70 }
           71 //---------------------------
           72 if (mud==null){
           73 out.print("<error>Login First(No Session)</error>");
           74 } else{
           75 //Folder folder=mud.getFolder();
           76 try  {
           77 //------------------------
           78 Store store=mud.getStore();
           79 Folder  folder=store.getFolder("INBOX");
           80 folder.open(Folder.READ_ONLY);
           81 //------------------------
           82 Message m=folder.getMessage(msgid);
           83 //if(partid==-1){
           84 if (nodepara==null){
           85 //if(!imgs.isEmpty())imgs.clear();
           86 messageHtml="";
           87 attachment="";
           88 recipients=getAllgetRecipients(m);
           89 out.print(displayMessage(request,m,partid));
           90 } else{
           91 displayPart(m,nodepara,response,out);
           92 }
           93 }  catch (MessagingException e) {
           94 e.printStackTrace();
           95 }  catch (IOException e) {
           96 e.printStackTrace();
           97 }  catch (Exception e) {
           98 e.printStackTrace();
           99 }
          100 }
          101 }       
          102 protected  void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          103 doGet(request,response);
          104 }  
          105 String  stdUrl="";
          106 String  url="";
          107 String  msgidStr="";
          108 String  messageHtml="";
          109 String  attachment="";
          110 String  recipients="";
          111 String  nodeid="";
          112 int  currentnodeid=0;
          113 String  node="";
          114 HashMap<String,Part> imgs=new HashMap<String,Part>();
          115 public  String displayMessage(HttpServletRequest request,Part p,int partid) throws Exception{
          116 //System.out.println("Type:"+p.getContentType());
          117 if (currentnodeid==1&&!node.endsWith("0")){
          118 nodeid=nodeid.substring(0,(nodeid.length()-2));
          119 }
          120 node=nodeid+currentnodeid;
          121 System.out.println(node);
          122 if (p.isMimeType("multipart/*")){
          123 nodeid+=currentnodeid+"-";
          124 Multipart mp=(Multipart) p.getContent();
          125 int  cnt=mp.getCount();
          126 String  mpct=mp.getContentType().toLowerCase();
          127 for (int i=0;
          128 i<cnt;
          129 i++){
          130 if (mpct.startsWith("multipart/alternative")&&mp.getBodyPart(i).getContentType().toLowerCase().startsWith("text/plain"))continue;
          131 currentnodeid=i;
          132 displayMessage(request,mp.getBodyPart(i),i);
          133 }
          134 }
          135 if (p.isMimeType("text/plain")||p.isMimeType("text/html")){
          136 if (messageHtml=="") {
          137 messageHtml=(String)p.getContent();
          138 //System.out.println(messageHtml);
          139 }  else {
          140 messageHtml=messageHtml+"<HR/>"+(String)p.getContent();
          141 //System.out.println(messageHtml);
          142 }
          143 }  else if (p.isMimeType("message/rfc822")) {
          144 //Nested Message
          145 //displayMessage(request,(Part)p.getContent(),partid);
          146 else{
          147 if (node.length()>2)    node=node.substring(2);
          148 System.out.println(node);
          149 String  disposition=p.getDisposition();
          150 //System.out.println("disposition:"+disposition);
          151 if (disposition!=null&&disposition.equalsIgnoreCase(Part.ATTACHMENT)){
          152 String  filename=getFileName(p);
          153 //imgs.put(filename,p);
          154 //attachment全部放入內存,會造成內存膨脹;若及時清空又造成Back回來的頁面訪問不到Attachment
          155 //attachment+=","+"<a href='"+url+"/"+filename+"?"+msgidStr+"&partid="+partid+"'>"+filename+"</a>";
          156 attachment+=","+"<a href='"+url+"/"+filename+"?"+msgidStr+"&node="+node+"'>"+filename+"</a>";
          157 //attachment+=","+"<a href='"+url+"/"+filename+"?"+"&partname="+getFileName(p)+"'>"+filename+"</a>";
          158 //System.out.println(attachment);
          159 else{
          160 //if(disposition!=null&&disposition.equalsIgnoreCase(Part.INLINE)){
          161 if (getCid(p)!=null)    {
          162 //System.out.println("Enter Replace");
          163 imgs.put(getFileName(p),p);
          164 //String uri=url+"?"+msgidStr+"&partid="+partid;
          165 String  uri=url+"?"+msgidStr+"&node="+node;
          166 //String uri=url+"?"+"&partname="+getFileName(p);
          167 String  t=messageHtml.substring(messageHtml.indexOf(getCid(p))-1);
          168 if (!(t.startsWith("\"")||t.startsWith("\'"))){
          169 uri="'"+uri+"'";
          170 }
          171 messageHtml=messageHtml.replace(getCid(p),uri);
          172 //System.out.println("cid:"+getCid(p));     
          173 //System.out.println(uri);
          174 }
          175 }
          176 }
          177 return  messageHtml+"attachhncwx="+attachment+recipients;
          178 }
          179 public  void displayPart(Message m,String node,HttpServletResponse response,ServletOutputStream out) 
          180 throws MessagingException, IOException{
          181 Part part = getPart(m,node);
          182 String  sct = part.getContentType();
          183 response.setContentType(sct);
          184 outPut(part,out);
          185 }
          186 private  Part getPart(Part m, String nodes) throws NumberFormatException, MessagingException, IOException {
          187 if (node==null)return m;
          188 String  node=nodes.substring(0,1);
          189 System.out.println(nodes+" : "+node);
          190 int  nid=Integer.parseInt(node);
          191 if (m.getContent()==null)System.out.print("no content");
          192 Part p=((Multipart)m.getContent()).getBodyPart(nid);
          193 if (nodes.length()>2)nodes=nodes.substring(2);
          194 else  {
          195 if (nodes.length()==1)nodes="";
          196 }
          197 if (nodes.length()>0)p=getPart(p,nodes);
          198 return  p;
          199 }
          200 public  void displayPart(String partname,HttpServletResponse response,    ServletOutputStream out) throws MessagingException, IOException{
          201 //System.out.println(imgs.keySet()+":"+partname);
          202 Part part=imgs.get(partname);
          203 String  ct=part.getContentType();
          204 if (ct!=null)        response.setContentType(ct);
          205 //=====Start push Stream into out
          206 InputStream in=part.getInputStream();
          207 ByteArrayOutputStream bos=new ByteArrayOutputStream();
          208 byte [] buffer=new byte[8192];
          209 int  count=0;
          210 while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);
          211 in .close();
          212 try{
          213 out.write(bos.toByteArray());
          214 out.flush();
          215 } catch(Exception e){
          216 }
          217 out.close();
          218 //=====End
          219 }
          220 public  void displayPart(Message m,int partid,HttpServletResponse response,        ServletOutputStream out) throws MessagingException, IOException{
          221 Multipart mp = (Multipart)m.getContent();
          222 Part part = mp.getBodyPart(partid);
          223 String  sct = part.getContentType();
          224 // ContentType ct = new ContentType(sct);
          225 response.setContentType(sct);
          226 if  (sct == null) {
          227 out.println("invalid part");
          228 return;
          229 }
          230 //=====Start push Stream into out
          231 InputStream in=part.getInputStream();
          232 ByteArrayOutputStream bos=new ByteArrayOutputStream();
          233 byte [] buffer=new byte[8192];
          234 int  count=0;
          235 while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);
          236 in .close();
          237 try{
          238 out.write(bos.toByteArray());
          239 out.flush();
          240 } catch(Exception e){
          241 }
          242 out.close();
          243 //=====End
          244 }
          245 private  String getFileName(Part p) throws MessagingException, UnsupportedEncodingException{
          246 //System.out.println("filename:");
          247 String  filename=p.getFileName();
          248 if (filename==null)return null;
          249 filename=new String(filename.getBytes("ISO-8859-1"),"GB2312");
          250 int  indexStart=filename.toUpperCase().indexOf("=?GB");
          251 if (indexStart>-1){
          252 filename=filename.substring(0,indexStart)+MimeUtility.decodeText(filename.substring(indexStart));
          253 }
          254 return  filename;
          255 }
          256 private  String getCid(Part p) throws MessagingException{
          257 String  cidraw=null,cid=null;
          258     
          259 String [] headers=p.getHeader("Content-id");
          260 if (headers!=null && headers.length>0) {
          261 cidraw=headers[0];
          262 } else{
          263 return  null;
          264 }
          265 if (cidraw.startsWith("<")&&cidraw.endsWith(">")) {
          266 cid="cid:"+cidraw.substring(1,cidraw.length()-1);
          267 }  else {
          268 cid="cid:"+cidraw;
          269 }
          270 return  cid;
          271 }
          272 /**
          273 * 獲得郵件的收件人,抄送,和密送的地址和姓名,根據(jù)所傳遞的參數(shù)的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
          274 @throws Exception 
          275 */
          276 private  String getAllgetRecipients(Message m) throws Exception{
          277 return  "mailaddrTo="    +getRecipients(m,"TO")
          278 +"mailaddrCc="+getRecipients(m,"CC")
          279 +"mailaddrBcc="+getRecipients(m,"BCC");
          280 }
          281 private  String getRecipients(Message m,String type) throws Exception {
          282 StringBuffer mailaddr = new StringBuffer("");
          283 String  addtype = type.toUpperCase();
          284 InternetAddress[] address = null;
          285 if  (addtype.equals("TO")) {
          286 address = (InternetAddress[]) m.getRecipients(Message.RecipientType.TO);
          287 }  else if (addtype.equals("CC")) {
          288 address = (InternetAddress[]) m.getRecipients(Message.RecipientType.CC);
          289 }  else {
          290 address = (InternetAddress[]) m.getRecipients(Message.RecipientType.BCC);
          291 }
          292 if  (address != null) {
          293 for  (int i = 0;
          294 i < address.length;
          295 i++) {
          296 String  email = address[i].getAddress();
          297 if  (email == null)
          298 email = "";
          299 else  {
          300 email = MimeUtility.decodeText(email);
          301 }
          302 String  personal = address[i].getPersonal();
          303 if  (personal == null)
          304 personal = "";
          305 else  {
          306 personal = MimeUtility.decodeText(personal);
          307 }
          308 mailaddr.append("\""+personal+"\" ");
          309 mailaddr.append("<");
          310 mailaddr.append(email);
          311 mailaddr.append(">");
          312 mailaddr.append(",");
          313 }
          314 }
          315 if (mailaddr.length()>0)mailaddr.deleteCharAt(mailaddr.length()-1);
          316 return  mailaddr.toString();
          317 }
          318 private  void outPut(Part part,ServletOutputStream out) throws IOException, MessagingException{
          319 //=====Start push Stream into out
          320 InputStream in=part.getInputStream();
          321 ByteArrayOutputStream bos=new ByteArrayOutputStream();
          322 byte [] buffer=new byte[8192];
          323 int  count=0;
          324 while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);
          325 in .close();
          326 try{
          327 out.write(bos.toByteArray());
          328 out.flush();
          329 } catch(Exception e){
          330 }
          331 out.close();
          332 //=====End
          333 }
          334 }




          posted on 2006-07-02 08:17 春天花會開 閱讀(9436) 評論(14)  編輯  收藏

          評論

          # re: javamail讀取完整的郵件 2006-07-06 18:55 純凈水

          如果同時收取100封這樣的郵件速度怎樣?  回復  更多評論   

          # re: javamail讀取完整的郵件 2006-07-07 08:16 luchunwei

          我沒有試過100封,一般作為網絡郵件(servlet)都是一封接一封的讀,速度還可以。我前端用Ajax異步處理也沒有發(fā)現(xiàn)什么問題。

          注:最近發(fā)現(xiàn)接收.eml時出現(xiàn)ClassCase Exception.
            回復  更多評論   

          # re: javamail讀取完整的郵件 2006-08-25 09:47 wbw

          能解釋一下文中的從頁面獲得的變量都代表什么嗎?  回復  更多評論   

          # re: javamail讀取完整的郵件 2006-08-25 10:14 春天花會開

          我在旁邊追加了注釋,你看看清楚了嗎  回復  更多評論   

          # re: javamail讀取完整的郵件 2006-09-26 21:39 holy

          這樣一個Servlet完成所有的功能感覺結構不好,如果能做一些封裝,比如使得業(yè)務代碼和MUA無關就好了,這樣以后不用javamail,換其他的也方便。  回復  更多評論   

          # re: javamail讀取完整的郵件 2008-02-28 08:58 armysky

          樓主:
          能不能把你做好的給我發(fā)一份!
            回復  更多評論   

          # re: javamail讀取完整的郵件 2008-05-28 12:05 紫凝

          MailUserData以及Login代碼能否給我一份。我是初學者。不能根據(jù)您的程序自己寫出這兩個類、麻煩您了。我的QQ:16211803 MSN:27091497@163.com  回復  更多評論   

          # re: javamail讀取完整的郵件 2008-06-02 21:06 luchunwei

          》@紫凝 你的QQ需要暗號
          請看我的另一篇文章《 LuEmail 客戶端+服務器代碼全部開放 》
            回復  更多評論   

          # re: javamail讀取完整的郵件 2008-07-14 12:03 shcuo

          import chunwei.mail.Login;


          import chunwei.mail.MailUserData;
          這個2類是自己寫的什么類?  回復  更多評論   

          # re: javamail讀取完整的郵件 2008-07-15 16:36 luchunwei

          Login、MailUserData是自己寫的類,主要負責登錄和保持用戶信息。  回復  更多評論   

          # re: javamail讀取完整的郵件 2008-07-27 00:28 shuo

          不導入這個類型可以用吧。。。注釋不太清楚。。。
          新手看不懂  回復  更多評論   

          # re: javamail讀取完整的郵件 2008-07-27 00:33 xuchao

          樓主可以發(fā)一份完整的給我嗎,可以最好有測試的。。。
          你的這個我不還是看得不大懂
          我的郵箱shcuo@163.com
            回復  更多評論   

          # re: javamail讀取完整的郵件 2008-07-28 18:54 luchunwei

          @shuo
          >>>
          可以的,過不你需要指定用戶名和密碼,并且自己處理郵箱登陸的過程,因為這是servlet,我在登陸后把相關的信息保存到session里,以便在整個回話過程中都可以方便使用。
            回復  更多評論   

          # re: javamail讀取完整的郵件 2012-05-17 10:55 philosoft

          樓主,我是新手,我覺得注釋應該多一點,要不然看不太明白。  回復  更多評論   


          只有注冊用戶登錄后才能發(fā)表評論。


          網站導航:
           
          主站蜘蛛池模板: 昌乐县| 宜城市| 罗城| 中西区| 邵阳市| 囊谦县| 新竹县| 高阳县| 葫芦岛市| 通化县| 城市| 灵台县| 上杭县| 大丰市| 正镶白旗| 印江| 双峰县| 杭锦后旗| 西昌市| 周口市| 车致| 青阳县| 改则县| 德惠市| 漳州市| 尖扎县| 海兴县| 金湖县| 新野县| 延川县| 漠河县| 吉水县| 大田县| 若羌县| 外汇| 中宁县| 重庆市| 会东县| 望城县| 龙南县| 宁安市|