j2me使用ksoap2开发webservice应用

今天突然心血来潮想写写关于j2me开发一些心的。

因为项目需要需要使用j2me开发,并且需要调用远程服务器,开始使用JSR 172开发,后来发现很多手机并不支持JSR 172,如果您是针对特定机型来开发并且那款机器支持JSR 172标准的话,恭喜你,我的教程您可以不用看了,因为用JSR 172开发超级简单。

好了回到正题,正式开始讲解。

首先说点废话,您需要下载、以及kxml2。

下载地址:http://downloads.sourceforge.net/ksoap2/ksoap2-j2me-core-2.1.2.jar?modtime=1173974533&big_mirror=0

http://downloads.sourceforge.net/kxml/kxml2-2.3.0.jar?modtime=1151079308&big_mirror=0

您可以去这里下载,下载好了导入你的工程即可。

剩下的当然就是代码啦。。。呵呵

由于我是直接从项目中拷贝出来的,所以一些细节东西我就不进行更改了

现在贴上核心代码:

String serviceNamespace = WebServiceUrl.URL + "service/SalesDataCollectionService";//WebServiceUrl.URL 这里面存放了一个具体的url地址便于 我调试使用,我的地址里面写的其实是 http://localhost:8080/
String serviceURL = WebServiceUrl.URL + "service/SalesDataCollectionService";//具体用处不是很大,因为和上面的地址是一样的,用上面的地址也是一样能跟完成的。
String methodName = "getXtm12ByXtwpdm";//调用的具体方法。这个方法需要传入一个参数,返回一个bean给用户。

SoapObject request = new SoapObject(serviceNamespace, methodName);//这里是一些准备工作,具体用处我就不多介绍了,因为我也不是很明白

request.addProperty( "xtwpdm",getTextFieldXtwpdm().getString());//这里是传入的参数,如果是多条参数就多复制几下就行了。他是一个键值对应的,其实也是按添加顺序来做的,你只要按照顺序往里面添加就行了,不过我的习惯是按照服务器端的名字对应填入键值。

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//类似于创建了一个连接工厂,因为我英语很烂,所以具体什么意思我也没弄明白,反正照着敲就不会错。
envelope.bodyOut = request;//将填入参数的request放入envelope 当中
(new MarshalBase64()).register(envelope);//需要做一下转码,其实用处不是很大,不过做总比不做好。要不不同的系统谁知道会出现什么问题呢。

HttpTransport ht = new HttpTransport(serviceURL);//创建连接了
ht.debug = true;//可以为false
ht.call(null, envelope);//调用webservice了

if(envelope.getResponse()!=null){//判断是否返回结果,因为我这个是一个查询操作,是带有返回值的。byte[] bb = Base64.decode(envelope.getResponse().toString());将返回的结果进行转码,从string类型转换为byte[]数组,这个在后面我会介绍的,不要着急。

Xtm12Form xtm12 = Xtm12Form.deserialize(bb);//这个就是我们希望得到的那个bean。//bean的源码我会在后面公开的。

//既然得到的你要的bean了,剩下的就是你自己的事情了,自己该怎么向下进行都ok了。

//这个就是ksoap2的精华所在了。

 

 

}

 

 

下面给大家看看 我服务器端的代码

public byte[] getXtm12ByXtwpdm(String xtwpdm) {
   Xtm12 x = this.xtm12DAO.findById(xtwpdm);//得到我要的结果了

    Xtm12Form xf = new Xtm12Form();//将结果进行了封装
    xf.setKcjldw(x.getKcjldw());//因为涉及到商业机密,就简单的列出一个set方法了。
    return xf.serialize();//返回是要求是byte[],所以我在bean中做了一下封装。
}

 

现在该看看精华了Xtm12Form bean 的源码,

package com.MobileRDA.FormBean;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;

import com.MobileRDA.StringVector;

public class Xtm12Form {

private String xtwpdm = "";

private StringVector wsvPersonName = new StringVector();//这就是进行二进制转换的类,我们将来在网络上传输的任何东西都是用二进制传输的,然后在将二进制转换回我们需要的东西。
   
   public String getXtwpdm() {
   return xtwpdm;
}

public void setXtwpdm(String xtwpdm) {
   this.xtwpdm = xtwpdm;
}

public static Xtm12Form deserialize(byte[] data) {//将二进制还原为我们所需要的类
   ByteArrayInputStream bais = new ByteArrayInputStream(data);
   DataInputStream dis = new DataInputStream(bais);
   Xtm12Form wc = new Xtm12Form();
   try {
    wc.xtwpdm = dis.readUTF();

    bais.close();
    dis.close();
   } catch (Exception exc) {
//    exc.printStackTrace();
   }
   return wc;
}

public byte[] serialize() {//将我们的类转换为二进制便于网路传输。
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   DataOutputStream dos = new DataOutputStream(baos);
   try {
    dos.writeUTF(xtwpdm);

    wsvPersonName.writeObject(dos);
    baos.close();
    dos.close();
   } catch (Exception exc) {
//    exc.printStackTrace();
   }
   return baos.toByteArray();
}

}

 

StringVector类的源码:

/**

* Vector主要用来保存各种类型的对象(包括相同类型和不同类型的对象)。
* 但是在一些情况下使用会给程序带来性能上的影响。这主要是由Vector类的两个特点所决定的。
* 第一,Vector提供了线程的安全保护功能。即使Vector类中的许多方法同步。
* 但是如果你已经确认你的应用程序是单线程,这些方法的同步就完全不必要了。
* 第二,在Vector查找存储的各种对象时,常常要花很多的时间进行类型的匹配。
* 而当这些对象都是同一类型时,这些匹配就完全不必要了。
* 因此,有必要设计一个单线程的,保存特定类型对象的类或集合来替代Vector类
*/

package com.MobileRDA;

public class StringVector{

// 这儿的transient标示这个属性不需要自动序列化
private transient String[] data;
private int count;
public int size() {
   return count;
}

public StringVector() {
   // default size is 10
   this(10);
}

public StringVector(int initialSize) {
   data = new String[initialSize];
}

public void add(String str) {
   //     ignore null strings 
   if (str == null) {
    return;
   }
   ensureCapacity(count + 1);
   data[count++] = str;
}

private void ensureCapacity(int minCapacity) {
   int oldCapacity = data.length;
   if (minCapacity > oldCapacity)   {
    String oldData[] = data;
    int newCapacity = oldCapacity * 2;
    data = new String[newCapacity];
    System.arraycopy(oldData, 0, data, 0, count);
   }
}

public void remove(String str) {
   if (str == null)   {
    return; // ignore null str   
   }
   for (int i = 0; i < count; i++)   {
    //     check for a match 
    if (data[i].equals(str))    {
     System.arraycopy(data, i + 1, data, i, count - 1); // copy data 
     //     allow previously valid array element be gc'd 
     data[--count] = null;
     return;
    }
   }
}

public final String getStringAt(int index) {
   if (index < 0)   {
    return null;
   }   else if (index > count){
    return null; // index is > # strings 
   }   else{
    return data[index]; // index is good 
   }
}

public synchronized void writeObject(java.io.DataOutputStream s) throws java.io.IOException {
   //     Write out array length 
   s.writeInt(count);
   //     Write out all elements in the proper order.   
   for (int i = 0; i < count; i++)   {
    s.writeUTF(data[i]);
   }
}

public synchronized void readObject(java.io.DataInputStream s) throws java.io.IOException, ClassNotFoundException {
   //     Read in array length and allocate array   
   int arrayLength = s.readInt();
   data = new String[arrayLength];
   // 同步data的大小
   count = arrayLength;
   //     Read in all elements in the proper order.  
   for (int i = 0; i < arrayLength; i++)   {
    data[i] = s.readUTF();
   }
}
}

 

另外这个bean以及StringVector需要在服务器端和客户端都存在,不是一个单方面的。

好了,代码已经基本上写完了,剩下的就需要大家自己体会了。

你可能感兴趣的:(应用服务器,bean,webservice,网络应用,dos)