用J2ME实现简单电子邮件发送功能

  在GCF中并没有提供给我们能够发送电子邮件的API,J2ME的可选包也没有提供相关的功能。那么我们能用J2ME实现发送电子邮件功能嘛?答案是肯定的。本文将主要讲述如何在J2ME中实现发送电子邮件的功能。
  这里一个非常重要的思想就是代理。我们知道GCF提供给我们进行联网的能力了,比如通过Http联网。在MIDP2.0中甚至提供了socket联网的API。那么我们可以通过他们连接服务器端的程序比如servlet,然后servlet可以通过JavaMail提供的接口发送邮件。那么我们需要做的只是通过Http协议或者其他协议把邮件的标题、内容、收件人等发送给servlet。就是这个简单的思想却是非常灵活非常有用。
  首先我们构造一个Message类来代表发送的消息。它包括主题、收件人和内容三个字段。
  package com.j2medev.mail;
  public class Message
  {
  private String to;
  private String subject;
  private String content;
  public Message()
  {
  }
  public Message(String to,String subject,String content)
  {
  this.to=to;
  this.subject=subject;
  this.content=content;
  }
  public String getContent()
  {
  return content;
  }
  public void setContent(String content)
  {
  this.content=content;
  }
  public String getSubject()
  {
  return subject;
  }
  public void setSubject(String subject)
  {
  this.subject=subject;
  }
  public String getTo()
  {
  return to;
  }
  public void setTo(String to)
  {
  this.to=to;
  }
  public String toString()
  {
  return to+subject+content;
  }
  }
  在用户界面的设计上,我们需要两个界面。一个让用户输入收件人和主题,另一个用于收集用户输入的内容。由于TextBox要独占一个屏幕的,因此我们不能把他们放在一起。
  /*
  *Created on 2004-12-8
  *
  *TODO To change the template for this generated file go to
  *Window-Preferences-Java-Code Style-Code Templates
  */
  package com.j2medev.mail;
  import javax.microedition.lcdui.Form;
  import javax.microedition.lcdui.Item;
  import javax.microedition.lcdui.*;
  import javax.microedition.midlet.MIDlet;
  /**
  * author P2800
  *
  *TODO To change the template for this generated type comment go to Window-
  *Preferences-Java-Code Style-Code Templates
  */
  public class MainForm extends Form implements CommandListener
  {
  private MailClient midlet;
  private TextField toField;
  private TextField subField;
  private boolean first=true;
  public static final Command nextCommand=new Command("NEXT",Command.OK,1);
  public MainForm(MailClient midlet,String arg0)
  {
  super(arg0);
  this.midlet=midlet;
  if(first)
  {
  first=false;
  init();
  }
  }
  public void init()
  {
  toField=new TextField("To:",null,25,TextField.ANY);
  subField=new TextField("Subject:",null,30,TextField.ANY);
  this.append(toField);
  this.append(subField);
  this.addCommand(nextCommand);
  this.setCommandListener(this);
  }
  public void commandAction(Command cmd,Displayable disp)
  {
  if(cmd==nextCommand)
  {
  String to=toField.getString();
  String subject=subField.getString();
  if(to==""&&subject=="")
  {
  midlet.displayAlert("Null to or sub",AlertType.WARNING,this);
  }
  else
  {
  midlet.getMessage().setTo(to);
  midlet.getMessage().setSubject(subject);
  midlet.getDisplay().setCurrent(midlet.getContentForm());
  }
  }
  }
  }
  package com.j2medev.mail;
  import javax.microedition.lcdui.Command;
  import javax.microedition.lcdui.CommandListener;
  import javax.microedition.lcdui.Displayable;
  import javax.microedition.lcdui.TextBox;
  import javax.microedition.midlet.MIDlet;
  public class ContentForm extends TextBox implements CommandListener
  {
  private MailClient midlet;
  private boolean first=true;
  public static final Command sendCommand=new Command("SEND",Command.ITEM,
  1);
  public ContentForm(String arg0,String arg1,int arg2,int arg3,
  MailClient midlet)
  {
  super(arg0,arg1,arg2,arg3);
  this.midlet=midlet;
  if(first)
  {
  first=false;
  init();
  }
  }
  public void init()
  {
  this.addCommand(sendCommand);
  this.setCommandListener(this);
  }
  public void commandAction(Command cmd,Displayable disp)
  {
  if(cmd==sendCommand)
  {
  String content=this.getString();
  midlet.getMessage().setContent(content);
  System.out.println(midlet.getMessage());
  try
  {
  synchronized(midlet)
  {
  midlet.notify();
  }
  }catch(Exception e)
  {
  }
  }
  }
  }
  最后我们完成MIDlet,在其中包括联网的程序代码,由于本站已经提供了很多关于J2ME联网的介绍,因此这里不再进行更多的解释。
  package com.j2medev.mail;
  import java.io.DataOutputStream;
  import java.io.IOException;
  import javax.microedition.midlet.MIDlet;
  import javax.microedition.midlet.MIDletStateChangeException;
  import javax.microedition.lcdui.*;
  import javax.microedition.io.*;
  public class MailClient extends MIDlet
  {
  private MainForm mainForm;
  private ContentForm contentForm;
  private Display display;
  private Message message;
  public Message getMessage()
  {
  return message;
  }
  public void setMessage(Message message)
  {
  this.message=message;
  }
  public void displayAlert(String text,AlertType type,Displayable disp)
  {
  Alert alert=new Alert("Application Error");
  alert.setString(text);
  alert.setType(type);
  alert.setTimeout(2000);
  display.setCurrent(alert,disp);
  }
  public ContentForm getContentForm()
  {
  return contentForm;
  }
  public Display getDisplay()
  {
  return display;
  }
  public MainForm getMainForm()
  {
  return mainForm;
  }
  public void initMIDlet()
  {
  MailThread t=new MailThread(this);
  t.start();
  message=new Message();
  display=Display.getDisplay(this);
  mainForm=new MainForm(this,"Simple Mail Client");
  contentForm=new ContentForm("Content",null,150,TextField.ANY,this);
  display.setCurrent(mainForm);
  }
  protected void startApp()throws MIDletStateChangeException
  {
  initMIDlet();
  }
  protected void pauseApp()
  {
  }
  protected void destroyApp(boolean arg0)throws MIDletStateChangeException
  {
  }
  }
  class MailThread extends Thread
  {
  private MailClient midlet;
  public MailThread(MailClient midlet)
  {
  this.midlet=midlet;
  }
  public void run()
  {
  synchronized(midlet)
  {
  try
  {
  midlet.wait();
  }
  catch(Exception e)
  {
  e.printStackTrace();
  }
  }
  System.out.println("connecting to server.....");
  HttpConnection httpConn=null;
  DataOutputStream dos=null;
  try
  {
  httpConn=(HttpConnection)Connector.open("http://localhost:8088/mail/maildo");
  httpConn.setRequestMethod("POST");
  dos=new DataOutputStream(httpConn.openOutputStream());
  dos.writeUTF(midlet.getMessage().getTo());
  dos.writeUTF(midlet.getMessage().getSubject());
  dos.writeUTF(midlet.getMessage().getContent());
  dos.close();
  httpConn.close();
  System.out.println("end of sending mail");
  }
  catch(IOException e)
  {}
  }}
  在服务器端,我们要完成自己的servlet。他的任务比较简单就是接受客户端的数据然后通过JavaMail发送到指定的收件人那里。如果您对JavaMail还不熟悉请参考如下文章。这里直接给出servlet代码。
  使用JavaMail实现收发电子邮件功能
  使用Servlet发送电子邮件
  package com.j2medev.servletmail;
  import java.io.DataInputStream;
  import java.io.IOException;
  import java.util.Properties;
  import javax.servlet.ServletConfig;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.mail.*;
  import javax.mail.internet.InternetAddress;
  import javax.mail.internet.MimeMessage;
  import java.util.*;
  import java.net.*;
  public class MailServlet extends HttpServlet
  {
  private static String host;
  private static String from;
  public void init(ServletConfig config)throws ServletException
  {
  super.init(config);
  host=config.getInitParameter("host");
  from=config.getInitParameter("from");
  System.out.println(host+from);
  }
  protected void doGet(HttpServletRequest request,
  HttpServletResponse response)throws ServletException,IOException
  {
  doPost(request,response);
  }
  protected void doPost(HttpServletRequest request,
  HttpServletResponse response)throws ServletException,IOException
  {
  DataInputStream dis=new DataInputStream(request.getInputStream());
  String send=dis.readUTF();
  String subject=dis.readUTF();
  String content=dis.readUTF();
  try
  {
  Properties props=System.getProperties();
  //Setup mail server
  props.put("mail.smtp.host",host);
  //Get session
  Session session=Session.getDefaultInstance(props,null);
  //Define message
  MimeMessage message=new MimeMessage(session);
  //Set the from address
  message.setFrom(new InternetAddress(from));
  //Set the to address
  message.addRecipient(Message.RecipientType.TO,new InternetAddress(
  send));
  //Set the subject
  message.setSubject(subject);
  //Set the content
  message.setText(content);
  //Send message
  Transport.send(message);
  }catch(Exception e)
  {
  e.printStackTrace();
  }
  }
  }
  web.xml
  <?xml version="1.0"?>
  <!DOCTYPE web-app PUBLIC"-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd">
  <web-app>
  <servlet>
  <servlet-name>ServletMail</servlet-name>
  <servlet-class>com.j2medev.servletmail.MailServlet</servlet-class>
  <init-param>
  <param-name>host</param-name>
  <param-value>smtp.263.net</param-value>
  </init-param>
  <init-param>
  <param-name>from</param-name>
  <param-value>eric.zhan 263.net</param-value>
  </init-param>
  </servlet>
  <servlet-mapping>
  <servlet-name>ServletMail</servlet-name>
  <url-pattern>/maildo</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <error-page>
  <error-code>404</error-code>
  <location>/error.jsp</location>
  </error-page>
  </web-app>
  总结:本文更多要介绍的其实还是这个代理的思想,利用所学的知识灵活应用。不要局限于J2ME提供给你的API。文章中实现的客户端服务器都比较简单,也不够友好,如果感兴趣可以稍微修饰一下,对提高能力还是有帮助的。在MIDP中只是提供了RMS作为持久存储用,因此实现接受存储邮件不是很方便。如果手机支持FileConnection的话可以编写一个接受邮件的客户端。