J2ME联网中采用序列化机制

类别:Java 点击:0 评论:0 推荐:
在CLDC中并没有对序列化机制进行支持,但是这并不影响我们在J2ME联网或者RMS操作中使用这种有效的机制,本文将讲述如何采用序列化机制进行J2ME联网。

    如果读者对TOMCAT的使用和Java IO还不熟悉那么请参考如下两篇文章,作为本文的准备。Java的基本数据类型与流,Tomcat入门指南。我们要编写一个用户注册的应用程序,用户填写自己的信息然后通过联网把数据发送到服务器,在Server端我们用Servlet来接收用户的数据。这样有一个好处就是当我们需要修改用户注册的选项的时候,比如添加一个选项,我们不需要修改程序的联网部分,只需要修改用户类的序列化和反序列化方法就可以了。下面看看我们的Account类,它是对用户的注册信息进行封装,并提供了两个重要的方法serialize()和deserialize()。
package com.j2medev.mingjava;

import java.io.*;

public class Account
{
    private String userName = "";
    private String email = "";
    private int age = 0;
    private boolean gender = false;

    public Account()
    {

    }

    public Account(String userName, String email, int age, boolean gender)
    {
        this.userName = userName;
        this.email = email;
        this.age = age;
        this.gender = gender;
    }

    public void serialize(DataOutputStream dos) throws IOException
    {
        dos.writeUTF(userName);
        dos.writeUTF(email);
        dos.writeInt(age);
        dos.writeBoolean(gender);
       
    }

    public static Account deserialize(DataInputStream dis) throws IOException
    {
        Account account = new Account();
        account.userName = dis.readUTF();
        account.email = dis.readUTF();
        account.age = dis.readInt();
        account.gender = dis.readBoolean();
      
        return account;
    }

    public String toString()
    {
        return "UserName = " + userName + " Email = " + email + " age = " + age
                + " gender = " + (gender ? "male" : "female");
    }
}
当我们进行联网操作的时候,只需要调用account.serialize(dos),例如
        private void connect(String url)
        {
            HttpConnection httpConn = null;
            DataOutputStream dos = null;
            InputStream is = null;
            try
            {
                System.out.println("connecting to server.....");
                httpConn = (HttpConnection) Connector.open(url);
                httpConn.setRequestMethod(HttpConnection.POST);
                dos = new DataOutputStream(httpConn.openOutputStream());
                System.out.println(account.toString());
                account.serialize(dos);
                dos.close();

            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }
服务器端收到客户端传送过来的Stream后,处理起来更简单,调用Account.deserialize(dis)就可以得到account对象了。
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException
    {
        int length = request.getContentLength();
        System.out.println(length);
        DataInputStream dis = new DataInputStream(request.getInputStream());
        Account myAccount = Account.deserialize(dis);
        System.out.println(myAccount.toString());
    }

    我们下面做个简单的MIDlet,目的是收集用户填写的注册信息然后发送给服务器。界面如下所示:

 

 

 

 

 

 

代码如下所示:

package com.j2medev.mingjava;

import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import java.io.*;
import javax.microedition.io.*;


public class NetworkMIDlet extends MIDlet implements CommandListener
{

    private Display display;
    private Form mainForm;
    private TextField userName;
    private TextField email;
    private TextField age;
    private ChoiceGroup gender;
    private NetworkThread nt;

    public static final Command connectCommand = new Command("Connect",
            Command.ITEM, 2);
    public static final Command exitCommand = new Command("Exit", Command.EXIT,
            1);
    public static final String URL = "http://localhost:8088/net/myservlet";

    protected void startApp() throws MIDletStateChangeException
    {
   
        initMIDlet();       

    }
   
    private void initMIDlet()
    {
        display = Display.getDisplay(this);
        mainForm = new Form("个人信息");
        userName = new TextField("姓名",null,20,TextField.ANY);
        email = new TextField("电子信箱",null,25,TextField.EMAILADDR);
        age = new TextField("年龄",null,20,TextField.ANY);
        gender = new ChoiceGroup("性别",Choice.EXCLUSIVE);
        gender.append("男",null);
        gender.append("女",null);
        mainForm.append(userName);
        mainForm.append(email);
        mainForm.append(age);
        mainForm.append(gender);
        mainForm.addCommand(connectCommand);
        mainForm.addCommand(exitCommand);
        mainForm.setCommandListener(this);
        display.setCurrent(mainForm);
        nt = new NetworkThread(this);
        nt.start();
    }

    private void exitMIDlet()
    {
        try
        {
            destroyApp(false);
            notifyDestroyed();
        } catch (MIDletStateChangeException e)
        {
            e.printStackTrace();
        }
    }


    protected void pauseApp()
    {
            }


    protected void destroyApp(boolean arg0) throws MIDletStateChangeException
    {
            }


    public void commandAction(Command arg0, Displayable arg1)
    {
        if(arg0 == connectCommand)
        {
            String name = userName.getString();
            String mail = email.getString();
            int myAge = Integer.parseInt(age.getString());
            int i = gender.getSelectedIndex();
            boolean myGender = i==0?true:false;
            Account account = new Account(name,mail,myAge,myGender);
            nt.setAccount(account);
        //   System.out.println(account.toString());
            synchronized(this)
            {
                notify();
            }             
           
        }
        else if(arg0 == exitCommand)
        {
            exitMIDlet();
        }

    }

    class NetworkThread extends Thread
    {
        private NetworkMIDlet midlet;
        private boolean going = true;
        private Account account = null;

        public NetworkThread(NetworkMIDlet midlet)
        {
            this.midlet = midlet;
        }

        public synchronized void setAccount(Account account)
        {
            this.account = account;
        }

        public void run()
        {
            while (going)
            {
                synchronized (midlet)
                {
                    try
                    {
                        midlet.wait();
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
                connect(URL);

            }
        }

        private void connect(String url)
        {
            HttpConnection httpConn = null;
            DataOutputStream dos = null;
            InputStream is = null;
            try
            {
                System.out.println("connecting to server.....");
                httpConn = (HttpConnection) Connector.open(url);
                httpConn.setRequestMethod(HttpConnection.POST);
                dos = new DataOutputStream(httpConn.openOutputStream());
                System.out.println(account.toString());
                account.serialize(dos);
                dos.close();

            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

}

    服务器端我们只是把从客户端发送过来的数据反序列化后打印到控制台。Servlet的代码如下所示:
import java.io.DataInputStream;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class MyServlet extends HttpServlet
{

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

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException
    {
        int length = request.getContentLength();
        System.out.println(length);
        DataInputStream dis = new DataInputStream(request.getInputStream());
        Account myAccount = Account.deserialize(dis);
        System.out.println(myAccount.toString());
    }
}
一定要把Account类也放到Server端,这样才可以实现反序列化的。(注意client和server的package并不一定)。启动Tomcat服务器,当客户端向服务器发送数据后,我们就可以在服务器端看到了。

本文地址:http://com.8s8s.com/it/it15437.htm