javamail读取完整的邮件

javamail读取完整的邮件

Javamail API虽然功能封装的比较完整,但是要写一个能正确显示复杂邮件的程序还有很多逻辑和细节要处理。下面是我最近做一个webmail时整理的Servlet,基本上可以正确的读取text,HTML,HTML中显示图片及附件。在本servlet中也简单处理了常见的中文问题,包括主题、附件、HTML图片中文、email Address中文。总体感觉有两个难点:1、附件和网页图片的抓取,需要定位数节点nodeid,光用partid是不行的;2、中文分两种情况Base64和客户端服务器端编码不一致。本程序中实现了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: [email protected]
 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; // 节点编号,如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  * 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同 "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 }




你可能感兴趣的:(javamail读取完整的邮件)