Android通过ksoap2传递复杂数据类型,服务端为CXF发布的webservice,亲手写的代码

来源:互联网 发布:淘宝退货运费差价 编辑:程序博客网 时间:2024/05/21 06:21

最近在学校搞点东西,搞了2天的webservice,心累呀,今天中午和小伙伴终于弄通了,感觉就是一些细节问题没有注意到,啊,我的时间呀,进这么过去了,为了不让小伙伴们走弯路,我还是认真的把开发文档写一遍吧!

首先,如果我们要用CXF发布webservice用自定义类型的对象来当参数传递的话,我们应该先把这个类序列化一遍,下面就是我测试的代码,我创建了一个TGrade类,实现了KvmSerializable接口,这个接口里面的三个方法,这个接口的好处在于不需要服务端在去反序列化实体对象了,

public class TGrade implements KvmSerializable {    // Fields    private Integer GId;    private Integer GMax;    private Integer GMin;    private String GName;    private String GPic;    private String GType;        // Constructors    /** default constructor */    public TGrade() {    }    /** minimal constructor */    public TGrade(Integer GMax) {        this.GMax = GMax;    }    /** full constructor */    public TGrade(Integer GMax, Integer GMin, String GName, String GPic,            String GType) {        this.GMax = GMax;        this.GMin = GMin;        this.GName = GName;        this.GPic = GPic;        this.GType = GType;    }    // Property accessors    public Integer getGId() {        return this.GId;    }    public void setGId(Integer GId) {        this.GId = GId;    }    public Integer getGMax() {        return this.GMax;    }    public void setGMax(Integer GMax) {        this.GMax = GMax;    }    public Integer getGMin() {        return this.GMin;    }    public void setGMin(Integer GMin) {        this.GMin = GMin;    }    public String getGName() {        return this.GName;    }    public void setGName(String GName) {        this.GName = GName;    }    public String getGPic() {        return this.GPic;    }    public void setGPic(String GPic) {        this.GPic = GPic;    }    public String getGType() {        return this.GType;    }    public void setGType(String GType) {        this.GType = GType;    }    @Override    public Object getProperty(int arg0) {        switch (arg0) {          case 0:              return GId;          case 1:              return GMax;          case 2:              return GMin;          case 3:              return GName;          case 4:              return GPic;        case 5:              return GType;          default:              break;          }          return null;      }    @Override    public int getPropertyCount() {        // TODO Auto-generated method stub        return 6;//y要注意这里,必须等于参数的个数,不然服务端没有办法接受有些参数    }    @Override    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {        switch (arg0) {        case 0:              arg2.type = PropertyInfo.STRING_CLASS;              arg2.name = "GId";              break;          case 1:              arg2.type = PropertyInfo.STRING_CLASS;              arg2.name = "GMax";              break;          case 2:              arg2.type = PropertyInfo.STRING_CLASS;              arg2.name = "GMin";              break;          case 3:              arg2.type = PropertyInfo.STRING_CLASS;              arg2.name = "GName";              break;          case 4:              arg2.type = PropertyInfo.STRING_CLASS;              arg2.name = "GPic";              break;          case 5:              arg2.type = PropertyInfo.STRING_CLASS;              arg2.name = "GType";              break;          default:              break;          }            }    @Override    public void setProperty(int arg0, Object arg1) {        switch (arg0) {        case 0:            GId=Integer.parseInt(arg1.toString());            break;        case 1:            GMax=Integer.parseInt(arg1.toString());            break;        case 2:            GMin=Integer.parseInt(arg1.toString());            break;        case 3:            GName=arg1.toString();            break;        case 4:            GPic=arg1.toString();            break;        case 5:            GType=arg1.toString();            break;        default:            break;        }    }}//-----------------------------下面是我测试部分的代码,这部分代码很重要,需要认真的看,我也写的比较详细,代码的世界模糊不得public boolean addMaintenanceInfo() {        String methodName = "addGrade";//服务端的方法        String soapAction =“http://10.127.80.67/gbckf/Android/GradeService”+methodName;                TGrade person = new TGrade();        person.setProperty(0, "6");        person.setProperty(1, 1);        person.setProperty(3, "1");        person.setProperty(4, "1");        person.setProperty(5, "1");        // 建立webservice连接对象        HttpTransportSE transport = new HttpTransportSE(AgbcApi.GRADESERVICEURL,5000);//5秒超时        transport.debug = true;// 是否是调试模式        // 设置连接参数        SoapObject soapObject = new SoapObject(AgbcApi.NAMESPACE, methodName);        PropertyInfo objekt = new PropertyInfo();        objekt.setName("arg0");//这个arg0很重要,不能是其他的东西,只能是arg0,不要问我为何,不然你就永远接受不了参数,因为是xml文档类型的东西        objekt.setValue(person);        objekt.setType(TGrade.class);        soapObject.addProperty(objekt);        // 设置返回参数        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);// soap协议版本必须用SoapEnvelope.VER11(Soap        envelope.dotNet = false;// 注意:这个属性是对dotnetwebservice协议的支持,如果dotnet的webservice        envelope.bodyOut = transport;        Log.i("请求参数", soapObject.toString());        envelope.setOutputSoapObject(soapObject);// 设置请求参数            envelope.addMapping(AgbcApi.NAMESPACE, "addGrade", TGrade.class);// 传对象时必须,参数namespace是webservice中指定的,            (new MarshalBase64()).register(envelope);            try {            transport.call(soapAction, envelope);            if(envelope.bodyIn instanceof SoapFault){                String str = ((SoapFault) envelope.bodyIn).faultstring;                Log.i("空节点返回的东西", str);            }else {                // SoapObject sb = (SoapObject)envelope.bodyIn;//服务器返回的对象存在envelope的bodyIn中                Object obj = envelope.getResponse();// 直接将返回值强制转换为已知对象                //Log.d("WebService", "返回结果:" + obj.toString());            }        }        catch (IOException e) {            e.printStackTrace();        }        catch (XmlPullParserException e) {            e.printStackTrace();        }        catch (Exception ex) {            ex.printStackTrace();        }        return true;


上面是我亲手写的代码,若是没有明白小伙伴,给我留言我给你看看吧,注意请求网络不能放在主线程哦,不然要报错的







2 0