网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  在rms中存储和读取数据     
  文章作者:未知  文章来源:水木森林  
  查看:93次  录入:管理员--2007-11-17  
 

■ 引言

  在上讲中,我们认识到汲取音乐播放的专长,能够制作成拥有bgm和音效、表现力丰富的应用程序。在本讲中,我们主要就应用程序本身内部保持的数据保存、读取进行详细阐述。

■ 数据的保存读取

  rms:

  要在应用程序中保存用户设定和高分等相关信息,所以必须在手机终端上的记忆中保存数据。midp上定义了称之为rms(record management system)的数据库系统。rms中有称为“record store”的列表,其中存在名为record 的entry。record按照字节排列,用id可以识别。利用下面的类、接口可以操作record store和record。

 类、接口名 作用
 recordstore 表示record store的类
 recordenumeration列举record的接口
 recordcomparator定义record comparator的接口
 recordfilter定义record过滤的接口
 recordlistener监视record store变更的接口

表 1

  recordstore

  表示record store的是record store类。record store是用recordstore 中的static方法的open record store制作的。

  recordstore.openrecordstore("recordstorename", true);

  第2个自变量转化成“true”后,名为“record store name”的record store存在的情况下,能够打开保存的record store。但是,名为“record store name”的record store不存在的情况下,则会制作新的record store,并打开所制作的record store 。

  第2个自变量转化成“false”后,名为“record store name”的record store存在的情况下,能够打开保存的record store。但,不存在的情况下,则放弃record store not found exception。
操作record store时,应该在操作前打开record store,并在操作完后关闭record store。利用刚刚介绍的record store的static方法——open record store打开record store。利用record store的引证方法的close record store按照下面的叙述可以关闭record store。在这儿将关闭的record store 例子表示为rs。

  rs.closerecordstore();

  以下是表示针对 record store 的连贯操作。(ex. 1)

recordstore rs = null;
try{
    // 打开record store
    rs = recordstore.openrecordstore("recordstorename",true);

    记述针对record store的操作
    ?
    ?

}catch(exception e){
}finally{
    if(rs != null){
        try{
            // 关闭record store
            rs.closerecordstore();
        }catch(exception e){
        }
    }
}

ex. 1

  按照下面所述的record store的static方法清除record store。
  recordstore.deleterecordstore("recordstorename");

  rms的限制

  rms是非常单纯的数据库系统,所以只需准备最小限度的操作。因此,一般数据库系统所具有的处理控制和系统故障的恢复功能,在rms上是不能被支持的。

  record操作

    增加record

    利用以下record store类的方法增加record 。

    int addrecord(byte[] data,int offset, int numbytes)

    在data中指定希望保存的数据字节排列、在offset中指定数据显示排列中的数据开始位置、在numbytes中指定保存数据的字节数。能在numbytes中指定0。此时,null被收藏在record中。另外,增加数据的record的id作为返还值返还。

    清除record

    利用以下方法清除record 。

    void deleterecord(int recordid)

    指定用recordid清除record中的id。对应的record不存在的情况下,放弃例外。而且,清除后的recordrecordid也不能再次利用。

    更改record

    利用以下方法更改record 。

    void setrecord(int recordid, byte[] newdata, int offset, int numbytes)

    指定recordid中更改的record,并在newdata中指定新收藏的数据字节排列。对应的record不存在的情况下,放弃例外。

    获取record

    利用下面的方法获取record。

    int getrecord(int recordid, byte[] buffer, int offset)

    byte[] getrecord(int recordid)

    上述方法是指,从offset的位置上复制recordid方法指定的record内容到buffer字节排列。返还值是所复制的数据的字节数。

    下面的方法是指,recordid所指定的record内容作为返还值返还。

  record store的信息

  利用如下方法可以获得record store操作和record 操作之外的record store信息。

 方法 功能
 public int getlastmodified() 用long获取最后的修改时刻。用system.currenttimemillis()形成能够取得的形式相同的形式。
 public int getnextrecordid()获取下一个recordid
 public int getnumrecords()获取record store中的record 数。
 public int getversion()获取record store的版本编号。版本编号通常在每次修改完record store后都会自动加1。
 public int getsizeavailable()获取record store的容许量。
 public int getsize()获取record store的占有字节数。
 public static string[] listrecordstores()全部获取record store名。

表 2

  recordenumeration

  rms中准备了能够访问record store中的全部record 的recordenumeration接口。由于厂商进行具体实际安装,所以开发者就没必要实际安装recordenumeration了。recordenumeration是具有双向链接的list,在各自的note中都保存了recordid。

    制作recordenumeration

    利用下面的record store instance方法制作recordenumeration。

    recordenumeration enumeraterecords(recordfilter filter, recordcomparator comparator, boolean keepupdated)

    一旦keepupdated成为true,就会增加record store中的record 的更改量,同时recordenumeration也会随着更新。成为false时,只要不呼出recordenumeration接口的rebuild()方法,即使在record store上增加变更,也不能反映,但可能会得到清除后的recordid。在filter中将用于过滤record的recordfilter接口指定为实际安装的类的接口。此外,在comparator中将用于定义record顺序号的recordcomparator接口指定为实际安装的类的接口。后面将详细说明。

    访问record

   应用以下方法访问利用recordenumeration的record。

 方法作用
 void destroy()取消recordenumeration
 boolean hasnextelement()调查是否有下一个record
 boolean haspreviouselement()调查是否有前一个record
 byte[] nextrecord()取得下一个record
 int nextrecordid()取得下一个record的id
 byte[] previousrecord()取得前一个record
 int previousrecordid()取得前一个record的id
 int numrecords()取得record的数
 void rebuild()再构筑recordenumeration
 void reset()将record的pointer返回到开头

表 3

  如下所示的是利用recordenumeration所取得的简单record。

import javax.microedition.midlet.*;
import javax.microedition.rms.*;

/**
* 表示record store的内容
*/
public class recordstoretest1 extends midlet {

    /**
    * 启动时运行的方法
    */
    protected void startapp() throws midletstatechangeexception {

        recordstore rs = null;
        recordenumeration re = null;
        try {

            rs = recordstore.openrecordstore("test",true);//读取record store
            re = rs.enumeraterecords(null,null,true);// 列举record

            // 取得并表示record
            byte[] data;
            while(re.hasnextelement()){
            data = re.nextrecord();
            system.out.println("record =" + data);
        }

        } catch (exception e) {
        } finally {
            // 取消record 的列举
            if (re != null) {
                try {
                        re.destroy();
                } catch (exception e) {
                }
            }

            // 关闭record store
            if (rs != null) {
                try {
                    rs.closerecordstore();
                }catch(exception e){
                }
            }
        }

    }

    protected void pauseapp() { }

    protected void destroyapp(boolean arg0) throws midletstatechangeexception { }

}

ex. 2

  recordfilter

  用recordenumeration取得record时,指定条件能够过滤record。实际安装recordfilter接口,该instance在recordenumeration完成时就成为构造函数的自变量,所以能够过滤。recordfilter接口中定义了如下方法。

  boolean matches(byte[] candidate)

  此方法中记述了过滤的条件,还记述了若条件适合则返回到true,若不合适则会返回到false。

  以下显示的是实际安装完recordfilter的testfilter。此例中过滤了比用构造函数所指定的数值还低的数值。

import javax.microedition.rms.recordfilter;

/**
* record过滤
* 过滤被指定的数值以下的数值
*/
public class testfilter implements recordfilter {

    private int min;// 数值的下限

    /**
    * 构造函数
    */
    public testfilter(int min){
        this.min = min;
    }

    /**
    * 过滤
    */
    public boolean matches(byte[] data) {
        if(data[0] > min){
            return true;
        }else{
        return false;
        }
    }
}

ex. 3

  在取得ex. 2的程序的recordenumeration画面中,将程序更改为

  re = rs.enumeraterecords(new testfilter(4),null,true);

  在自变量上指定ex. 3的testfilter时的运行结果如下所示。(图 1)。

在rms中存储和读取数据(图一) 
recordcomparator

  用recordenumerator取得record时,能够进行利用recordcomparator接口所取得的record的comparator。recordcomparator中定义了下面方法。

  int compare(byte[] rec1, byte[] rec2)

  返还值中返还了以下3个定数。

 recordcomparator.precedes在comparator上record rec1到达record rec2的前一位置时
 recordcomparator.follows在comparator上record rec1到达record rec2的后一位置时
 recordcomparator.equivalent在comparator上record rec1到达record rec2的同一位置时

表 4

  以下显示的是实际安装recordcomparator的testcomparator。在此例中,按照数值的大小顺序进行比测record。(ex. 4)

import javax.microedition.rms.recordcomparator;

/**
* 比较record并定义comparator顺序
*/
public class testcomparator implements recordcomparator {

    /**
    * 比较record
    */
    public int compare(byte[] rec1, byte[] rec2) {

        if(rec1[0] == rec2[0]){
            return recordcomparator.equivalent;
        }else if(rec1[0] > rec2[0]){
            return recordcomparator.precedes;
        }else {
            return recordcomparator.follows;
        }
    }
}

ex. 4

  取得ex. 2程序的recordenumeration的画面中,程序变更为

  re = rs.enumeraterecords(new testfilter(3),new testcomparator,true);

  并自变量中指定ex. 4的testcomparator时的运行结果。该内容如下图所示(图 2)。

在rms中存储和读取数据(图二)
图 2

  recordlistener

  利用recordlistener接口,能够监视针对record store的变更。例如,同期取得两个record store的情况下,单方面的record store被更改时,能够实现在单方的record store上增加更改等的操作。

  recordlistener中有recordchanged,recordadded,recorddeleted等3个种类的事件,并分别定义了每个方法。

  void recordadded(recordstore recordstore, int recordid)

  void recordchanged(recordstore recordstore, int recordid)

  void recorddeleted(recordstore recordstore, int recordid)

  利用record store类中所准备的如下方法能够在record store 上登记recordlistener。

  void addrecordlistener(recordlistener listener)

  void removerecordlistener(recordlistener listener)

  以下是实际安装recordlistener的instance。此示范程序中,可以监视并复制record的操作。

import javax.microedition.midlet.*;
import javax.microedition.rms.*;

/**
* 表示record store内容
*/
public class recordstoretest2 extends midlet implements recordlistener{

    /**
    * 启动时所运行的方法
    */
    protected void startapp() throws midletstatechangeexception {

        recordstore rs = null;
        recordenumeration re = null;
        try {
            rs = recordstore.openrecordstore("test",true);// 读取record store
            recordfilter filter = new testfilter(3);
            recordcomparator comparator = new testcomparator();

            // 增加recordlistener
            rs.addrecordlistener(this);

            // 将数据加入record store
            if(rs.getnumrecords() < 1){
                byte[] data = new byte[1];
                for(int i=0;i < 10;i++){
                    data[0] = (byte)i;
                    rs.addrecord(data,0,data.length);
                }
            }

            // 增加record
            byte[] data = new byte[1];
            data[0] = (byte)3;
            rs.addrecord(data,0,data.length);

            // 清除record
            rs.deleterecord(7);

            // 更改record
            rs.setrecord(8,data,0,data.length);

            // 取得并表示record
            re = rs.enumeraterecords(filter,comparator,true);// 列举record
            while(re.hasnextelement()){
                data = re.nextrecord();
                system.out.println("record =" + data[0]);
            }

        } catch (exception e) {
        } finally {
            // 取消record 的列举
            if (re != null) {
                try {
                    re.destroy();
                } catch (exception e) {
                }
            }

            // 关闭record store
            if (rs != null) {
                try {
                    rs.closerecordstore();
                }catch(exception e){
                }
            }
        }
    }

    protected void pauseapp() { }

    protected void destroyapp(boolean arg0) throws midletstatechangeexception { }

    /**
    * 增加record 时的处理
    */
    public void recordadded(recordstore recordstore, int recordid) {
        try{
            system.out.println(recordstore.getrecord(recordid)[0]+"is added.");
        }catch(exception e){
        }
    }

    /**
    * 更改recordrecord时的处理
    */
    public void recordchanged(recordstore recordstore, int recordid) {
        try{
            system.out.println(recordstore.getrecord(recordid)[0]+"is changed");
        }catch(exception e){
        }

    }

    /**
    * 取消record时的处理
    */
    public void recorddeleted(recordstore recordstore, int recordid) {
        try{
            system.out.println(recordstore.getname()+"id:"+recordid+"is deleted.");
        }catch(exception e){
        }
    }

}

ex. 5

  下图是运行结果。(图3)该图能够确认record 操作内容是被监视并被表示的。

在rms中存储和读取数据(图三)
图3

  开始制作应用程序了。

  手机记事本的说明

  利用midp的rms功能,制作手机简易记事本应用程序。

  就是用户输入记事内容,保存输入的内容、并进行记事的编辑、清除等所谓的简单的记事本应用程序。

  如下是画面结构。

memo list画面显示memo list。可以进行memo的重新制作和显示。显示每个memo的最后访问日期和时间。
memo画面表示memo的内容。可以进行memo的编辑、清除。

  下图是画面迁移图。(图 4)

在rms中存储和读取数据(图四)
图 4

  手机记事本的实际安装

    下面是实际安装的顺序
    1. 制作模型
    2. 制作画面的实物模型
    3. 制作rms的操作

    1. 制作模型

  在本记事本中,要制作成表示一个一个的记事的memo类。memo类中有最后访问日期和时间、记事内容等属性。(ex. 6)

import java.io.*;
import java.util.*;


/**
* memo类
*/
public class memo {

    private date date;
    private string content = "";

    /**********************************
    * 构造函数
    **********************************/
    public memo(){
        date = new date();
    }

    public memo(string content, date date) {
        this.content = content;
        this.date = date;
    }

    /**********************************
    * getter & setter
    **********************************/
    /**
    * 取得内容
    */
    public string getcontent() {
        return content;
    }

    /**
    * 取得最后访问的日期和时间
    */
    public date getdate() {
        return date;
    }

    /**
    * 设定内容
    */
    public void setcontent(string string) {
        content = string;
        date = new date();
    }

    /**
    * 设定最后访问的日期和时间
    */
    public void setdate(date date) {
        this.date = date;
    }
}

ex. 6

2. 制作画面的实物模型

  接下来制作画面与画面之间的迁移。

  本讲讲述利用高级api制作画面。memo list用高级api的list表示,memo画面则利用textbox。

  而且,还要在各个画面中设定命令。分别设定如下表格所示的命令。

 memo list画面 add重新制作memo
 show显示memo
 memo画面 ok刷新memo的内容
 delete清除memo

  以下内容是实际安装画面实物模型的具体步骤。对于实物模型,sample source命令实际安装所记述的处理后,则应用程序就完成了。

import java.util.vector;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

/**
* 手机记事本(画面实物模型版)
*/
public class mobilememo extends midlet implements commandlistener {

    // 画面类
    private display display;
    private form inputform;
    private list list;
    private textbox memotext;

    // 命令群
    private command add = new command("add", command.ok, 1);
    private command show = new command("show", command.ok, 1);
    private command ok = new command("ok", command.ok, 1);
    private command delete = new command("delete", command.ok, 1);

    /**
    * 构造函数
    */
    public mobilememo() {
        display = display.getdisplay(this);

        // 完成memo list
        initializelist();

        // 作成记事显示画面
        initializememotext();

    }

    /**
    * 进行memo list的初期化
    */
    private void initilizelist(){
        list = new list("memo list", list.exclusive);
        list.addcommand(show);
        list.addcommand(add);
        list.setcommandlistener(this);
    }
    /**
    * 进行记事显示画面的初期化
    */
    private void initilizememotext(){
        memotext = new textbox("memo", "", 100, textfield.any);
        memotext.addcommand(ok);
        memotext.addcommand(delete);
        memotext.setcommandlistener(this);
    }

    /**
    // 开始应用程序
    */
    protected void startapp() throws midletstatechangeexception {

        // 从record store读取信息

        // 转换到memo list画面
        display.setcurrent(list);
    }

    /**
    // 暂时停止应用程序
    */
    protected void pauseapp() {}

    /**
    // 结束应用程序
    */
    protected void destroyapp(boolean bool) throws     midletstatechangeexception {}

    /**
    * 命令处理
    */
    public void commandaction(command c, displayable d) {

        if (d == list) {
            if (c == add) {
            // 重新制作memo

            } else if (c == show) {
            // 取得memo

            }

            // 转换到memo显示画面
            display.setcurrent(memotext);
        } else if (d == memotext) {
            if (c == ok) {
                // recordmemo内容

            } else if (c == delete) {
                // 清除memo内容
            }

            // 转换到memo list
            display.setcurrent(list);
        }
    }
}

  按照上面表格中的程序所示,则可完成实物模型,并能完成应用程序的大致框架。

    3. 完成rms的操作

    马上就要完成rms操作了。

    现在我们只想在 record store中原样保存memo内容,所以就要在刚才作成的memo类中进行精雕细琢。从取得memo类字节排列方法和字节排列中增加制作memo类的构造函数。而且,还能用memo类保存record id。(record store中保存的record id则不写入。)

    利用bytearrayoutputstream类和dataoutputstream类,变换字节排列中的类的内容。memo类中记述了如下instance方法。(ex. 7)

/**
* 变换字节排列
*/
public byte[] tobytes(){
    byte[] data = null;
    try{
        bytearrayoutputstream baos = new bytearrayoutputstream();
        dataoutputstream out = new dataoutputstream(baos);

        out.writelong(date.gettime());
        out.writeutf(content);
        data = baos.tobytearray();

        baos.close();
        out.close();

    }catch(exception e){
    }

    return data;
}

ex. 7

    还是从字节排列中制作作成memo对象的构造函数吧!利用bytearrayinputstream类、datainputstream类,如下记述。(ex. 8)

public memo(byte[] data){
    bytearrayinputstream bais = new bytearrayinputstream(data);
    datainputstream in = new datainputstream(bais);
    try{
        date = new date(in.readlong());
        content = in.readutf();
    }catch(exception e){
    }
}

ex. 8

    为能保持memo类中的record id ,增加一个属性。由此,则完成了memo类。以下程序显示的是完成后的memo类 。(ex. 9)

import java.io.*;
import java.util.*;


/**
* memo类
*/
public class memo {

    private int recid;
    private date date;
    private string content = "";

    /**********************************
    * 构造函数
    **********************************/
    public memo(){
        date = new date();
    }

    public memo(byte[] data){
        bytearrayinputstream bais = new bytearrayinputstream(data);
        datainputstream in = new datainputstream(bais);
        try{
            date = new date(in.readlong());
            content = in.readutf();
        }catch(exception e){
        }
    }

    public memo(string content, date date) {
        this.content = content;
        this.date = date;
    }


    /*********************************
    * instance方法
    *********************************/

    /**
    * 变换字节排列
    */
    public byte[] tobytes(){
        byte[] data = null;
        try{
            bytearrayoutputstream baos = new bytearrayoutputstream();
            dataoutputstream out = new dataoutputstream(baos);

            out.writelong(date.gettime());
            out.writeutf(content);
            data = baos.tobytearray();

            baos.close();
            out.close();

        }catch(exception e){
        }

        return data;
    }

    /**********************************
    * getter & setter
    **********************************/

    /**
    * 设定record id
    */
    public int getrecid(){
        return recid;
    }

    /**
    * 取得内容
    */
    public string getcontent() {
        return content;
    }

    /**
    * 取得最后访问的日期和时间
    */
    public date getdate() {
        return date;
    }

    /**
    * 设定内容
    */
    public void setcontent(string string) {
        content = string;
        date = new date();
    }

    /**
    * 设定最后访问的日期和时间
    */
    public void setdate(date date) {
        this.date = date;
    }

    /**
    * 设定record id
    */
    public void setrecid(int id){
        this.recid = id;
    }

}

ex. 9

接下来,开始在mobilememo类上制作rms操作吧。rms操作有如下四种方法。

  • 全部取得memo内容
  • 重新制作memo内容
  • 保存memo内容
  • 清除memo内容

    全部取得memo内容的方法中,利用recordenumeration全部取得record,并从取得的record字节排列中制作memo对象。制作完成的memo对象能够将vector型的memos作为instance变量加以定义,并在此保持。而且,从record store中全部取得完record 后,则可以按照record 更新record store画面。在此,定义了如下方法。(ex. 10)

/**
// 从record store更新信息
*/
public void reloadfromrsm() {
memos.removeallelements();

// 取得record
recordstore rs = null;
recordenumeration re = null;
try {
rs = recordstore.openrecordstore(rs_name, true);
re = rs.enumeraterecords(null, null, true);

// 取得record
while (re.hasnextelement()) {
int id = re.nextrecordid();// 取得record id
byte[] data = rs.getrecord(id);// 取得record
memo memo = new memo(data);// 完成memo
memo.setrecid(id);// 设定record id
memos.addelement(memo);// 增加memo
}

} catch (exception e) {
} finally {
// 取消recordenumeration
if (re != null) {
try {
re.destroy();
} catch (exception e) {
}
}
// 关闭record store
if (rs != null) {
try {
rs.closerecordstore();
} catch (exception e) {
}
}
}

// 更新memo list
initilizelist();
for (int i = 0; i < memos.size(); i++) {
memo memo = (memo) memos.elementat(i);
list.append(memo.getdate().tostring(), null);
}

}

ex. 10

    转换到memo list画面时呼出ex. 10的方法。

    接着,继续记述余下的操作。这些操作主要针对record store进行更改。即使将每一步操作步骤都详细记述也是没关系的,为了简单化,现在将针对record store的操作都整合在一个方法中,并记述根据if文的区分处理。(ex. 11)

/**
* 重新制作memo
*/
public memo createnewmemo() {
memo memo = new memo();
return changememotorms(memo, add);
}

/**
* 保存memo内容
*/
public void writememo(memo memo) {
changememotorms(memo, ok);
}

/**
* 消除memo
*/
public void deletememo(memo memo) {
changememotorms(memo, delete);
}

/**
* 在record store上反映memo的变更
*/
private memo changememotorms(memo memo, command c) {
recordstore rs = null;
try {
rs = recordstore.openrecordstore(rs_name, true);

// memo的更改被反映到record store
// 依据命令更改操作
if (c == ok) { // memo的编辑
int id = memo.getrecid();
rs.setrecord(id, memo.tobytes(), 0, memo.tobytes().length);
} else if (c == delete) { // 清除memo
int id = memo.getrecid();
rs.deleterecord(id);
} else if (c == add) { // 重新制作memo
int id = rs.addrecord(memo.tobytes(), 0, memo.tobytes().length);
memo.setrecid(id);
}
} catch (exception e) {
} finally {
if (rs != null) {
try {
rs.closerecordstore();
return memo;
} catch (exception e) {
}
}
}
return null;
}

ex. 11

    下面将完成的处理与命令处理结合在一起。(ex. 12)memo显示画面中显示的memo内容被保持为名为currentmemo的instance变量,并且在memo显示画面中,可以显示currentmemo内容。

/**
* 命令处理
*/
public void commandaction(command c, displayable d) {

if (d == list) {
if (c == add) {
// 重新制作memo
currentmemo = createnewmemo();
} else if (c == show) {
// 取得memo
int index = list.getselectedindex();
if(index == -1)return;
currentmemo = (memo) memos.elementat(index);
}

// 转入memo显示画面
memotext.setstring(currentmemo.getcontent());
display.setcurrent(memotext);
} else if (d == memotext) {
if (c == ok) {
// recordmemo内容
currentmemo.setcontent(memotext.getstring());
writememo(currentmemo);
} else if (c == delete) {
// 清除memo内容
deletememo(currentmemo);
}

// 转入memo list
reloadfromrsm();
display.setcurrent(list);
}
}

ex. 12

■ 完成

  本讲中所制作的源码如下所示:

  • mobilememo.java
  • memo.java

  运行后如下:

在rms中存储和读取数据(图五) 在rms中存储和读取数据(图六)

■ 总结

  在本讲中,介绍了利用rms可以进行数据保存和读取。由于利用这种功能,能够在应用程序内永久保存数据,所以能够制作成高级功能的应用程序。从下讲开始,计划介绍手机网络的有关知识。学习了第一讲[创建开发环境] 到第七讲的[网络],有关手机java的相关技术应该有个大概的轮廓了。以这些基础的java技术信息为基础,一定可以制作成出色的应用程序的!

 
 
上一篇: 开发midp联网应用程序    下一篇: 在midp应用程序中播放声音
  相关文档
java的垃圾回收(garbage collection)机制 11-17
java基础问题请教! 11-17
我眼中的java经典书籍 11-17
比尔学java:javasocket篇 11-17
在java中对标准流进行重定向 11-17
javabean 101 8 11-17
vector还是arraylist这是个问题 11-17
计算java日期:学习怎样创建和使用日期 12-14
java核心代码例程之:helloworld.java(2) 11-17
java调试教程--初步介绍 11-17
java 2 micro edition简介(四) 11-17
helloworld问题集精华 11-17
win2000 server iis+tomcat5多站点配置 11-16
解决jsp中的中文乱码 11-17
小技巧:java swing中使用双击事件 11-17
完全掌握java中的"包"机制 11-17
右移赋值运算符 (>>=) 11-16
java网络编程:ftp协议实现服务器详解 11-16
j2ee综合 svn配置手记 11-17
基于mock对象和junit框架简化spring web组件单元测试(1) 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息