如何在移动设备上实现一个简单的邮件客户端来接收邮件

本文介绍了一种在移动设备上实现简单邮件客户端的方法,利用HTTP协议与Servlet进行邮件收发的适配。通过示例代码详细展示了客户端与服务器端的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传统的,当我们接收邮件的时候,邮件客户端软件会连接到支持Post Office Protocol, Version 3 (POP3) or Internet Message Access Protocol, Version 4 (IMAP4) 协议的邮件服务器.
由于通常一个MIDLet是通过HTTP协议来和服务器进行数据交换,因此通常就需要一个Servlet来作为邮件接收适配器来实现接收邮件的功能。
接收邮件的代码由Servlet完成,MIDlet仅仅和Servlet进行交互并显示结果

下边的代码说明了如何在移动设备上实现一个简单的邮件客户端来接收邮件

/*运行在移动设备上的MIDlet*/
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.io.*;
import java.io.InputStream;
import java.io.PrintStream;


public class CheckMail extends MIDlet implements CommandListener {
    private String MAIL_SERVER_URL =
            "http://localhost:8080/examples/servlet/CheckMailServlet?";
    private int MSG_LIST_SIZE = 5;
    Display display = null;
    List menu = null;
    List dmenu = null;
    TextBox input = null;
    String[] msgs = new String[MSG_LIST_SIZE];
    String user = null;
   
    int status = 0;
    Command backCommand = new Command("Back", Command.BACK, 0);
    Command submitCommand = new Command("Submit", Command.OK, 2);
    Command exitCommand = new Command("Exit", Command.STOP, 3);
   
    public CheckMail() { }
   
    public void startApp()  throws MIDletStateChangeException {
        display = Display.getDisplay(this);
        displayMenu();
    }
   
    public void pauseApp() { }
   
    public void destroyApp(boolean unconditional) {
        notifyDestroyed();
    }
   
    public void commandAction(Command c,  Displayable d) {
        if(c == exitCommand ) {
            destroyApp(true);
        } else if (c == backCommand) {
            handleBack();
        } else if (c == submitCommand) {
            user = input.getString();
            retreiveMail(0, null);
        } else if (d == dmenu) {
            handleMainMenu();
        } else if (d == menu) {
            handleMsgMenu();
        } else
            loginUser();
    }
   
    /* 显示主屏幕 */
    private void displayMenu() {
        dmenu = new List("Check Email", Choice.IMPLICIT);
        if (user == null)
            dmenu.append("Login", null);
        else
            dmenu.append("Logout", null);
        dmenu.append("Check Mail", null);
        dmenu.addCommand(exitCommand);
        dmenu.setCommandListener(this);
        display.setCurrent(dmenu);
        status = 0;
    }
   
    /* 采集邮件地址和密码*/
    private void loginUser() {
        input = new TextBox(
                "Enter Login Name/Password (Seperate by /) :", "", 25,
                TextField.ANY);
       
        input.addCommand(submitCommand);
        input.addCommand(backCommand);
        input.setCommandListener(this);
        display.setCurrent(input);
    }
   
        /* 此方法取回邮件号码为msgNum的邮件,如果没有指定msgNum则显示所有邮件的列表*/
    private void retreiveMail(int s, String msgNum) {
       
        String popURL = MAIL_SERVER_URL + "u=" + user;
        if (s == 0)
            popURL = popURL // 登录
                    if (s == 1)
                        // 列出邮件
                        popURL = popURL + "&s=" + msgNum + "&a=l";
                    else if (s == 2)
                        // 取回邮件 i=msgNum
                        popURL = popURL + "&i=" + msgNum + "&a=r";
           
            StreamConnection c = null;
            InputStream is=null;
            StringBuffer sb = null;
            String err = null;
           
            try {
                c = (StreamConnection)Connector.open(popURL,
                        Connector.READ_WRITE);
               
                is = c.openInputStream();
                int ch;
                sb = new StringBuffer();
                while ((ch = is.read()) != -1) {
                    sb.append((char)ch);
                }
            } catch(Exception  ex){ err = ex.getMessage(); } finally {
                try {
                    if(is!= null) {is.close(); }
                    if(c != null) {c.close(); }
                } catch(Exception exp) { err = exp.getMessage(); }
            }
           
            if (err == null) {
                if (s == 0) {
                    user = sb.toString();
                   
                    if (user.indexOf("INVALIDUSR") >= 0) {
                        user = null;
                        showAlert("不正确的用户名和口令");
                    } else {
                        input = null;
                        dmenu = null;
                        displayMenu();
                    }
                } else if (s == 1) // 取回列表
                    showMList(sb.toString());
                else // s ==2, 显示邮件
                    showMsg(sb.toString());
            } else
                showAlert(err); // 显示错误页
    }
   
    /* 显示被选择的邮件*/
    private void showMsg(String msg) {
        StringBuffer buffer = new StringBuffer(200);
        int delim = '?';
        int j = msg.indexOf(delim);
        int i =0;
       
        // 获取 FROM
        buffer.append(msg.substring(0,j ));
        for (int k=0;k<4;k++) {
            i = j+1;
            j = msg.indexOf(delim, i);
            // 获取 TO, CC, Subject, Date
            buffer.append(msg.substring(i,j ));
        }
        // 邮件内容
        buffer.append("/n" + msg.substring(j+1 ));
        showAlert(buffer.toString());
    }
   
    /* 显示错误信息*/
    private void showAlert(String err) {
        Alert a = new Alert("");
        a.setString(err);
        a.setTimeout(Alert.FOREVER);
        display.setCurrent(a);
    }
   
    /* 显示邮件列表*/
    private void showMList(String msgStr) {
        for (int i=0;i<MAX_LIST_SIZE;i++) {
            msgs[i] = "";
        }
        menu = new List("Messages", Choice.IMPLICIT);
        int delim = '?';
        String sub = null;
        int i =0;
        int k = 0;
        int l =0;
        int j =msgStr.indexOf(delim);
        while( j >= 0) {
            sub = msgStr.substring(i,j);
            if ((k % 2) == 0) {
                msgs[l] = sub; // 第一项是邮件编号
                l++;
            } else
                menu.append(sub, null);
            k++;
            i = j + 1;
            j = msgStr.indexOf(delim, i);  
        }
        sub = msgStr.substring(i);
        menu.append(sub, null);
        menu.addCommand(backCommand);
        menu.addCommand(exitCommand);
        menu.setCommandListener(this);
        status = 1;
        display.setCurrent(menu);
    }
   
    private void handleBack() {
        if (status == 1) {
            dmenu = null;
            displayMenu();
        } else
            display.setCurrent(menu);
    }
   
    private void handleMainMenu() {
        int index = dmenu.getSelectedIndex();
        switch(index) {
            case 0 :
                if (user != null) {
                    retreiveMail(1, "0");
                    break;
                }
            case 1 :
                status = 1;
                loginUser();
                break;
            case 2 :
                break;
        }
    }
   
    private void handleMsgMenu() {
        int index = menu.getSelectedIndex();
        if (!msgs[index].equals("")) {
            retreiveMail(2, msgs[index]); // 获取邮件
        }
    }
}

/*和邮件服务器通讯的Servlet*/
import java.io.*;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import javax.servlet.*;
import javax.servlet.http.*;

public class CheckMailServlet extends HttpServlet {
    private static String  MSG_NOMAIL = "NOMAIL";
    private static String  MSG_INVALID_USER = "INVALIDUSR";
    private static String  MSG_CRITCAL_ERR = "UNEXPECTEDERROR";
   
    public CheckMailServlet() {
        String hostname = "yourserver.com"
                //获取系统属性
                Properties props = System.getProperties();
        props.put("mail.pop3.host", "hostname");
        Session session = Session.getDefaultInstance(props, null);
        Store store = session.getStore("pop3");
    }
   
    /*获取请求参数 */
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws IOException {
       
        try {
            String action = request.getParameter("a");
            if(action == null)
                doLogin(request, response);
            else if(action.equals("r")) //获取
                doRetrieve(request, response);
            else if(action.equals("l")) //列表
                doList(request, response);
        } catch(Exception e) {
            PrintWriter writer = response.getWriter();
            writer.println(MSG_CRITCAL_ERR);
            writer.flush();
        }
    }
   
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws IOException {
       
        doGet(request, response);
    }
   
    /* 执行登录操作*/
    private void doLogin(HttpServletRequest request,
            HttpServletResponse response) throws ServletException,
            IOException, MessagingException {
       
        String uid = request.getParameter("u");
        String pwd, tmpUID ;
        String responeStr = null;
        if ((uid == null) || (uid.equals("")) ) {
            responeStr = MSG_INVALID_USER;
        } else {
            int j =uid.indexOf('/');
            if (j > 0) {
                tmpUID = uid.substring(0,j);
                pwd = uid.substring(j+1);
                if(login(tmpUID,pwd)) {
                    responeStr = tmpUID;
                    flag = true;
                } else
                    responeStr = MSG_INVALID_USER;
            } else
                responeStr = MSG_INVALID_USER;
        }
        PrintWriter writer = response.getWriter();
        writer.print(responeStr);
        writer.flush();
    }
   
    public boolean login(String uid, String pwd) // 登录
    {
        store.connect(hostname,uid,pwd);
        if (store.isConnected()) {
            return true;
        } else
            return false;
    }
   
    /* 列出收件箱中所有的邮件*/
    private void doList(HttpServletRequest request,
            HttpServletResponse response) throws ServletException,
            IOException, MessagingException {
       
        String uid = request.getParameter("u");
        String responeStr = "";
        MailLister lister = null;
        StringBuffer buffer = new StringBuffer(200);
        try {
            lister = getMailLister(uid);
        } catch(Exception exp) {
            throw new ServletException(exp.getMessage());
        }
        if ( (lister != null) &&  (lister.size() > 0)) {
            Vector vect = lister.keys();
            int listSize =  vect.size();
            int endingNum = (listSize > 8) ? (listSize - 8) : 0;
            for (int j = listSize-1; j>=endingNum; j--) {
                String curKey = (String)vect.elementAt(j);
                String msgString = (String)lister.get(curKey);
                if (j != endingNum)
                    buffer.append( curKey + "?" + msgString + "?");
                else
                    buffer.append(curKey + "?" + msgString);
            }
            responeStr =  buffer.toString();
        } else
            responeStr = MSG_NOMAIL;
        PrintWriter writer = response.getWriter();
        writer.print(responeStr);
        writer.flush();
    }
   
    /* 将所有的邮件存在Hashtable里 */
    private MailLister getMailLister(String uid) throws Exception {
        MailLister lister = null;
        int j =uid.indexOf('/');
        String ud;
        String pwd;
        if (j > 0) {
            ud = uid.substring(0,j);
            pwd = uid.substring(j+1);
            if(login(ud,pwd)) {
                // 打开文件夹
                Folder folder = store.getDefaultFolder();
                if (folder == null) {
                    System.out.println("No default folder");
                    return null;
                }
                folder = folder.getFolder("INBOX");
                if (folder == null) {
                    System.out.println("Invalid folder");
                    return null;
                }
                folder.open(Folder.READ_ONLY);
                // 获得目录
                Message message[] = folder.getMessages();
                lister = new MailLister()
                for (int i=0, n=message.length; i<n; i++) {
                    Message m = folder.getMessage(i);
                    lister.put(m,i);
                }
            } else
                return lister;
        } else
            return lister;
        return lister;
    }
   
    /* 从收件箱中获取邮件编号为msgID的邮件*/
    private void doRetrieve(HttpServletRequest request,
            HttpServletResponse response) throws ServletException,
            IOException, MessagingException {
       
        String msgId = request.getParameter("i");
        String uid = request.getParameter("u");
        try {
            Message msg = getMessageFromStore(msgId, uid);
            if (msg == null)
                throw new ServletException(
                        "Could not Load the Message File");
            writeMessage(msg, request, response, uid, msgId);
        } catch(Exception exp) {
            throw new ServletException(exp.getMessage());
        }
    }
   
    private String getMsgHeading(Message msg) throws Exception {
        StringBuffer buffer = new StringBuffer(300);
        buffer.append("From:");
        getAddressesList(msg.getFrom(), buffer);
        buffer.append("    To:");
        getAddressesList(
                msg.getRecipients(javax.mail.Message.RecipientType.TO),
                                  buffer);
       
        buffer.append("    Subject:");
        buffer.append(msg.getSubject());
        buffer.append("    Date:");
        buffer.append(msg.getSentDate());
        return buffer.toString();
    }
   
    private void getAddressesList(Address addresses[], StringBuffer buffer)
    throws Exception {
        String uName;
        String uEmail;
        if(addresses != null) {
            for(int i = 0; i < addresses.length; i++) {
                buffer.append(addresses[i] + ";");
            }
        }
    }
   
    /* 根据MIME类型编写邮件然后发送给移动设备*/
    protected void writeMessage(Message msg, HttpServletRequest request,
            HttpServletResponse response, String uid, String msgId)
            throws Exception {
        if(msg.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart)msg.getContent();
            int msgPartCount = multipart.getCount();
            StringBuffer buffer = new StringBuffer(200);
            for(int i = 0; i < msgPartCount; i++) {
                Part p = multipart.getBodyPart(i);
                if (i == 0) {
                    buffer.append(getMsgHeading(msg));
                }
                if(p.isMimeType("text/plain")) {
                    String content = (String)p.getContent();
                    buffer.append(content.trim());
                } else {
                    String filename = p.getFileName();
                    buffer.append(" ---  Has attachement " + filename);
                }
                if (i == (msgPartCount-1)) {
                    response.setContentType("text/plain");
                    PrintWriter writer = null;
                    writer = response.getWriter();
                    writer.print(removeExtraChar(buffer.toString(), '/n'));
                    writer.flush();
                }
            }
        } else if(msg.isMimeType("text/plain")) {
            printAscii(response, (String)msg.getContent() , msg);
        } else // HTML或者其他类型的内容
        {
            writePart(msg, -1, response);
        }
    }
   
    private void printAscii(HttpServletResponse response,
            String currentText, Message msg ) throws Exception {
        PrintWriter writer = response.getWriter();
        if (currentText.length() > 1500)
            currentText = currentText.substring(0,1500);
        writer.print(getMsgHeading(msg) + currentText);
        writer.flush();
    }
   
    private Message getMessageFromStore(String msgUID, String uid)
        throws Exception {
       
        MailLister lister = getMailLister(uid)
        if(lister != null) {
            return lister.get(msgUID);
        } else
            return null;
    }
   
    private void writePart(Message msg, int partnr,
            HttpServletResponse response) throws Exception {
       
        Part p = msg;
        String responseStr ;
        if (p.isMimeType("text/html")) {
            String str = (String)p.getContent();
            if (str.length() > 1500)
                str = str.substring(0,1500);
            responseStr = removeHTMLFormatting(str);
            responseStr = removeExtraChar(responseStr, '/n');
        } else
            responseStr = "移动设备不支持此MIME类型的邮件";
       
        response.setContentType("text/plain");
        PrintWriter writer = response.getWriter();
        writer.print(getMsgHeading(msg) + responseStr);
        writer.flush();
    }
   
    private String removeHTMLFormatting(String str) {
        boolean insideTag = false;
        String token;
        StringBuffer buffer = new StringBuffer(200);
        StringTokenizer st = new StringTokenizer( str , "<>", true);
        while( st.hasMoreTokens() ) {
            token = st.nextToken();
            if ( token.equals( "<" ) )
                insideTag = true;
            else if ( token.equals( ">" ) )
                insideTag = false;
            else if ( insideTag == false )
                buffer.append( token );
        }
        return buffer.toString();
    }
   
    private String removeExtraChar(String str, int delim) {
        StringBuffer buffer = new StringBuffer(200);
        // 第一个子串
        int j =str.indexOf(delim); 
        int i = 0;
        while( j >= 0) {
            // Add some extra space
            buffer.append("    " + str.substring(i,j));
            i = j + 1;
            j = str.indexOf(delim, i);   // 剩下的子串
        }
        buffer.append(str.substring(i)); // 最后一个子穿
        return buffer.toString();
    }
   
        /* 这个MailLister类存储所有的邮件到一个Hashtable中并且可以根据指定的key取回这些邮件*/
    public class MailLister implements  java.io.Serializable {
        private Hashtable hash;
        private Vector vect;
        public MailLister() {
            vect = new Vector();
            hash = new Hashtable(vect.capacity());
        }
       
        public Object get(Object obj) {
            return hash.get(obj);
        }
       
        public void put(Object key, Object val) {
            if(!vect.contains(key))
                vect.insertElementAt(key, vect.size());
            hash.put(key, val);
        }
    }
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值