javamail读取完整的邮件

来源:互联网 发布:菜鸟网络的运营模式 编辑:程序博客网 时间:2024/05/16 07:47
Javamail API虽然功能封装的比较完整,但是要写一个能正确显示复杂邮件的程序还有很多逻辑和细节要处理。下面是我最近做一个webmail时整理的 Servlet,基本上可以正确的读取text,HTML,HTML中显示图片及附件。在本servlet中也简单处理了常见的中文问题,包括主题、附件、HTML图片中文、email Address中文。总体感觉有两个难点:1、附件和网页图片的抓取,需要定位数节点nodeid,光用partid是不行的;2、中文分两种情况 Base64和客户端服务器端编码不一致。本程序中实现了3种displayPart()的方法,具体情况不同结合使用效率更高。本程序还有一个未处理的地方就是我在做nodeid的时候最多算10个。当然还有其他问题欢迎指正,来出是为了给后来的初学者作个参考例子,少走弯路。 


 
import  java.io.IOException;

import  java.io.InputStream;

import  java.io.UnsupportedEncodingException;

import  java.util.HashMap;

import  javax.mail.Folder;

import  javax.mail.Message;

import  javax.mail.MessagingException;


import  javax.mail.Multipart;

import  javax.mail.Part;

import  javax.mail.Store;

import  javax.mail.internet.InternetAddress;

import  javax.mail.internet.MimeUtility;

import  javax.servlet.ServletException;


import  javax.servlet.ServletOutputStream;

import  javax.servlet.http.HttpServletRequest;

import  javax.servlet.http.HttpServletResponse;

import  javax.servlet.http.HttpSession;

import  chunwei.mail.Login;


import  chunwei.mail.MailUserData;

/**
* Servlet implementation class for Servlet: MailServlet
* Author: luchunwei  Email: luchunwei@gmail.com
*/ 

public  class MailNode extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

private  static final long serialVersionUID = 1L;


protected  void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

nodeid="";

node="0";

currentnodeid=0;

url=request.getRequestURL().toString();

HttpSession ses=request.getSession();


MailUserData mud=(MailUserData)ses.getAttribute("mud");

ServletOutputStream out=response.getOutputStream();

response.setContentType("text/html;charset=GB2312");

int  msgid=-1,partid=-1;

String  partname=null;


String  nodepara=null;

if (request.getParameter("msgid")!=null) 

msgid=Integer.parseInt(request.getParameter("msgid"));

msgidStr="msgid="+msgid;

if (request.getParameter("partid")!=null) 

partid=Integer.parseInt(request.getParameter("partid"));


if (request.getParameter("partname")!=null) 

partname=new String(request.getParameter("partname").getBytes("ISO-8859-1"),"GB2312");

if (request.getParameter("node")!=null) 

nodepara=request.getParameter("node");


System.out.println(nodepara);

//System.out.println(msgid+":"+partid+":"+partname); 

if (partname!=null){

//displayImages 

try  {

displayPart(partname,response,out);


}  catch (MessagingException e) {

e.printStackTrace();



}  catch (IOException e) {

e.printStackTrace();




return;




//-------------------------- 

if (mud==null){

Login login=new Login("imap","mail.server.com",-1,"user","password");

login.login();

if (login.getResult()==1){


HttpSession session = request.getSession();

session.setMaxInactiveInterval(3600);

session.setAttribute("mud",login.getMud());




mud=(MailUserData)ses.getAttribute("mud");




//--------------------------- 

if (mud==null){

out.print("<error>Login First(No Session)</error>");


} else{

//Folder folder=mud.getFolder(); 

try  {

//------------------------ 

Store store=mud.getStore();

Folder  folder=store.getFolder("INBOX");


folder.open(Folder.READ_ONLY);

//------------------------ 

Message m=folder.getMessage(msgid);

//if(partid==-1){ 

if (nodepara==null){

//if(!imgs.isEmpty())imgs.clear(); 

messageHtml="";

attachment="";


recipients=getAllgetRecipients(m);

out.print(displayMessage(request,m,partid));


} else{

displayPart(m,nodepara,response,out);





}  catch (MessagingException e) {

e.printStackTrace();


}  catch (IOException e) {


e.printStackTrace();


}  catch (Exception e) {

e.printStackTrace();








}        

protected  void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


doGet(request,response);


}   

String  stdUrl="";

String  url="";

String  msgidStr="";

String  messageHtml="";

String  attachment="";

String  recipients="";

String  nodeid="";

int  currentnodeid=0;

String  node="";


HashMap<String,Part> imgs=new HashMap<String,Part>();

public  String displayMessage(HttpServletRequest request,Part p,int partid) throws Exception{

//System.out.println("Type:"+p.getContentType()); 

if (currentnodeid==1&&!node.endsWith("0")){

nodeid=nodeid.substring(0,(nodeid.length()-2));




node=nodeid+currentnodeid;

System.out.println(node);

if (p.isMimeType("multipart/*")){

nodeid+=currentnodeid+"-";


Multipart mp=(Multipart) p.getContent();

int  cnt=mp.getCount();

String  mpct=mp.getContentType().toLowerCase();

for (int i=0;

i<cnt;

i++){

if (mpct.startsWith("multipart/alternative")&&mp.getBodyPart(i).getContentType().toLowerCase().startsWith("text/plain"))continue;


currentnodeid=i;

displayMessage(request,mp.getBodyPart(i),i);







if (p.isMimeType("text/plain")||p.isMimeType("text/html")){

if (messageHtml=="") {

messageHtml=(String)p.getContent();

//System.out.println(messageHtml); 


}  else {

messageHtml=messageHtml+"<HR/>"+(String)p.getContent();

//System.out.println(messageHtml); 





}  else if (p.isMimeType("message/rfc822")) {

//Nested Message 

//displayMessage(request,(Part)p.getContent(),partid); 


} else{

if (node.length()>2)    node=node.substring(2);

System.out.println(node);

String  disposition=p.getDisposition();

//System.out.println("disposition:"+disposition); 

if (disposition!=null&&disposition.equalsIgnoreCase(Part.ATTACHMENT)){


String  filename=getFileName(p);

//imgs.put(filename,p); 

//attachment全部放入内存,会造成内存膨胀;若及时清空又造成Back回来的页面访问不到Attachment 

//attachment+=","+"<a href='"+url+"/"+filename+"?"+msgidStr+"&partid="+partid+"'>"+filename+"</a>"; 

attachment+=","+"<a href='"+url+"/"+filename+"?"+msgidStr+"&node="+node+"'>"+filename+"</a>";

//attachment+=","+"<a href='"+url+"/"+filename+"?"+"&partname="+getFileName(p)+"'>"+filename+"</a>"; 

//System.out.println(attachment); 


} else{

//if(disposition!=null&&disposition.equalsIgnoreCase(Part.INLINE)){ 

if (getCid(p)!=null)    {

//System.out.println("Enter Replace"); 

imgs.put(getFileName(p),p);

//String uri=url+"?"+msgidStr+"&partid="+partid; 

String  uri=url+"?"+msgidStr+"&node="+node;

//String uri=url+"?"+"&partname="+getFileName(p); 

String  t=messageHtml.substring(messageHtml.indexOf(getCid(p))-1);

if (!(t.startsWith("/"")||t.startsWith("/'"))){

uri="'"+uri+"'";




messageHtml=messageHtml.replace(getCid(p),uri);

//System.out.println("cid:"+getCid(p));      

//System.out.println(uri); 










return  messageHtml+"attachhncwx="+attachment+recipients;





public  void displayPart(Message m,String node,HttpServletResponse response,ServletOutputStream out)  

throws MessagingException, IOException{

Part part = getPart(m,node);

String  sct = part.getContentType();


response.setContentType(sct);

outPut(part,out);




private  Part getPart(Part m, String nodes) throws NumberFormatException, MessagingException, IOException {

if (node==null)return m;

String  node=nodes.substring(0,1);

System.out.println(nodes+" : "+node);

int  nid=Integer.parseInt(node);

if (m.getContent()==null)System.out.print("no content");

Part p=((Multipart)m.getContent()).getBodyPart(nid);

if (nodes.length()>2)nodes=nodes.substring(2);


else  {

if (nodes.length()==1)nodes="";




if (nodes.length()>0)p=getPart(p,nodes);

return  p;




public  void displayPart(String partname,HttpServletResponse response,    ServletOutputStream out) throws MessagingException, IOException{


//System.out.println(imgs.keySet()+":"+partname); 

Part part=imgs.get(partname);

String  ct=part.getContentType();

if (ct!=null)        response.setContentType(ct);

//=====Start push Stream into out 

InputStream in=part.getInputStream();

ByteArrayOutputStream bos=new ByteArrayOutputStream();

byte [] buffer=new byte[8192];

int  count=0;

while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);


in .close();

try{

out.write(bos.toByteArray());

out.flush();


} catch(Exception e){




out.close();

//=====End 




public  void displayPart(Message m,int partid,HttpServletResponse response,        ServletOutputStream out) throws MessagingException, IOException{


Multipart mp = (Multipart)m.getContent();

Part part = mp.getBodyPart(partid);

String  sct = part.getContentType();

// ContentType ct = new ContentType(sct); 

response.setContentType(sct);

if  (sct == null) {


out.println("invalid part");

return;




//=====Start push Stream into out 

InputStream in=part.getInputStream();

ByteArrayOutputStream bos=new ByteArrayOutputStream();

byte [] buffer=new byte[8192];


int  count=0;

while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);

in .close();

try{

out.write(bos.toByteArray());

out.flush();


} catch(Exception e){




out.close();

//=====End 




private  String getFileName(Part p) throws MessagingException, UnsupportedEncodingException{


//System.out.println("filename:"); 

String  filename=p.getFileName();

if (filename==null)return null;

filename=new String(filename.getBytes("ISO-8859-1"),"GB2312");

int  indexStart=filename.toUpperCase().indexOf("=?GB");


if (indexStart>-1){

filename=filename.substring(0,indexStart)+MimeUtility.decodeText(filename.substring(indexStart));




return  filename;




private  String getCid(Part p) throws MessagingException{

String  cidraw=null,cid=null;

     

String [] headers=p.getHeader("Content-id");

if (headers!=null && headers.length>0) {

cidraw=headers[0];


} else{

return  null;




if (cidraw.startsWith("<")&&cidraw.endsWith(">")) {

cid="cid:"+cidraw.substring(1,cidraw.length()-1);



}  else {

cid="cid:"+cidraw;




return  cid;




/**
* 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
* @throws Exception 
*/ 

private  String getAllgetRecipients(Message m) throws Exception{


return  "mailaddrTo="    +getRecipients(m,"TO") 

+"mailaddrCc="+getRecipients(m,"CC") 

+"mailaddrBcc="+getRecipients(m,"BCC");




private  String getRecipients(Message m,String type) throws Exception {


StringBuffer mailaddr = new StringBuffer("");

String  addtype = type.toUpperCase();

InternetAddress[] address = null;

if  (addtype.equals("TO")) {

address = (InternetAddress[]) m.getRecipients(Message.RecipientType.TO);



}  else if (addtype.equals("CC")) {

address = (InternetAddress[]) m.getRecipients(Message.RecipientType.CC);


}  else {

address = (InternetAddress[]) m.getRecipients(Message.RecipientType.BCC);




if  (address != null) {


for  (int i = 0;

i < address.length;

i++) {

String  email = address[i].getAddress();

if  (email == null) 

email = "";

else  {

email = MimeUtility.decodeText(email);




String  personal = address[i].getPersonal();


if  (personal == null) 

personal = "";

else  {

personal = MimeUtility.decodeText(personal);




mailaddr.append("/""+personal+"/" ");

mailaddr.append("<");

mailaddr.append(email);

mailaddr.append(">");


mailaddr.append(",");







if (mailaddr.length()>0)mailaddr.deleteCharAt(mailaddr.length()-1);

return  mailaddr.toString();




private  void outPut(Part part,ServletOutputStream out) throws IOException, MessagingException{


//=====Start push Stream into out 

InputStream in=part.getInputStream();

ByteArrayOutputStream bos=new ByteArrayOutputStream();

byte [] buffer=new byte[8192];

int  count=0;

while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);


in .close();

try{

out.write(bos.toByteArray());

out.flush();


} catch(Exception e){




out.close();

//=====End 






 
原创粉丝点击