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

最近在学校搞点东西,搞了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;


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







你可能感兴趣的:(Android通过ksoap2传递复杂数据类型,服务端为CXF发布的webservice,亲手写的代码)