Android調用WebService系列之對象構建傳遞

來源:互聯網
上載者:User

標籤:android   對象解析   ksoap2   對象構建傳遞   

上一篇我們講了如何封裝Android調用WebService的能力,把上一章的類加入我們便有了與WebService通訊的能力。往往我們會遇到WebService調用是通過對象來進行實際互動調用的。於是便有了這一章構建對象傳遞。

首先我們瞭解一下。

Ksoap2這個開源包裡面提供了一個介面

/* Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The  above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE.  * * Contributor(s): John D. Beatty, F. Hunter, Renaud Tognelli * * */package org.ksoap2.serialization;import java.util.Hashtable;/** * Provides get and set methods for properties. Can be used to replace * reflection (to some extend) for "serialization-aware" classes. Currently used * in kSOAP and the RMS based kobjects object repository */public interface KvmSerializable {    /**     * Returns the property at a specified index (for serialization)     *      * @param index     *            the specified index     * @return the serialized property     */    Object getProperty(int index);    /**      * @return the number of serializable properties      */    int getPropertyCount();    /**     * Sets the property with the given index to the given value.     *      * @param index     *            the index to be set     * @param value     *            the value of the property     */    void setProperty(int index, Object value);    /**     * Fills the given property info record.     *      * @param index     *            the index to be queried     * @param properties     *            information about the (de)serializer.  Not frequently used.     * @param info     *            The return parameter, to be filled with information about the     *            property with the given index.     */    void getPropertyInfo(int index, Hashtable properties, PropertyInfo info);}

 介面的有這麼一句話in kSOAP and the RMS based kobjects object repository,大致意思應該就是基於Object Storage Service的時候可以用到他。(當然藉助翻譯工具翻譯的,有什麼理解上錯誤的請聯絡我)

那麼意味著我們只需要把要傳遞的對象實現這個介面就可以實現對象傳輸了!

於是乎就有很多網文實現教你如何去實現了!我樣本一下!

public Test implements KvmSerializable{    public String test1;    public String test2;        //Returns the property at a specified index (for serialization)    //通過索引返回特定屬性(翻譯:返回屬性在指定的索引(序列化))    @Override    public Object getProperty(int index) {       //根據介面注釋最直接的會如下操作       switch(index){       ...(return test1 之類)       }        }    //return the number of serializable properties     //返回屬性的個數(翻譯:返回的數量可序列化的屬性)    @Override    public int getPropertyCount() {        // TODO Auto-generated method stub        //返回固定數量        return 2;    }    //Sets the property with the given index to the given value.    //根據index給PropertyInfo賦值參數 (翻譯:屬性與給定的索引設定為給定值。)    @Override    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo a) {                //根據介面注釋最直接的會如下操作        swtich(index){        ...  (設定a的屬性值)        }    }    // Fills the given property info record.    //給相應索引的屬性賦值(翻譯:填充給定屬性資訊記錄。)    @Override    public void setProperty(int index, Object arg1) {        switch(index){        ...(test1 = arg1之類)        }    }}

這樣是沒有錯誤的,但是在我們有很多不同的類需要傳遞的時候呢?這個類屬性上百個的時候呢?

那我們豈不是一直需要做重複操作。那麼我們何不寫一個通用的轉換類!

於是在不考慮更複雜,以及特定的一些資料類型的時候我們有了下面這個類:

import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.ArrayList;import java.util.Hashtable;import java.util.List;import java.util.Vector;import org.ksoap2.serialization.KvmSerializable;import org.ksoap2.serialization.PropertyInfo;import org.ksoap2.serialization.SoapObject;/** * 對象傳輸基礎類 * @author 劉亞林 * @e-mail [email protected] *  */public abstract BaseKvmSerializable implements KvmSerializable{    /**    ** 將首字母大寫    **/    public static String fristUpperCase(String str) {return String.valueOf(str.charAt(0)).toUpperCase().concat(str.substring(1));    }    //Returns the property at a specified index (for serialization)    //通過索引返回特定屬性(翻譯:返回屬性在指定的索引(序列化))    @Override    public Object getProperty(int index) {        //既然是要返回特定索引的屬性值,那麼我們何不直接通過反射取對應屬性返回       Field[] fs = this.getClass().getDeclaredFields();       Field f = fs[index];       String name = f.getName();       name = fristUpperCase(name);        String getMethodName = "get";if (f.getType() == boolean.class || f.getType() == Boolean.class) {    getMethodName = "is";}getMethodName += name;Method getMethod;Object val = null;try {getMethod = this.getClass().getMethod(getMethodName);getMethod.setAccessible(true);val = getMethod.invoke(this);} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}return val;       }    //return the number of serializable properties     //返回屬性的個數(翻譯:返回的數量可序列化的屬性)    @Override    public int getPropertyCount() {        // TODO Auto-generated method stub        //返回固定數量        return this.getClass().getDeclaredFields().length;    }    //Sets the property with the given index to the given value.    //根據index給PropertyInfo賦值參數 (翻譯:屬性與給定的索引設定為給定值。)    @Override    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo a) {                Field[] fs = this.getClass().getDeclaredFields();Field f = fs[index];String name = f.getName();//主要是設定type和name其他的需要可以繼續添加a.type = getTypeByClass(f.getType());a.name = name;    }    // Fills the given property info record.    //給相應索引的屬性賦值(翻譯:填充給定屬性資訊記錄。)    @Override    public void setProperty(int index, Object arg1) {        Field[] fs = this.getClass().getDeclaredFields();Field f = fs[index];String name = f.getName();name = fristUpperCase(name);String setMethodName = "set" + name;Method m;try {    m = this.getClass().getDeclaredMethod(setMethodName, f.getType());    m.setAccessible(true);    m.invoke(this, arg1); } catch (NoSuchMethodException e) {    // TODO Auto-generated catch block    e.printStackTrace();} catch (IllegalAccessException e) {            // TODO Auto-generated catch block    e.printStackTrace();} catch (IllegalArgumentException e) {    // TODO Auto-generated catch block    e.printStackTrace();} catch (InvocationTargetException e) {    // TODO Auto-generated catch block    e.printStackTrace();}      }    /**    **  根據類別獲得 PropertyInfo 特定類別     **  實際上除了統一類別這個沒什麼太多用為了心裡好過而加    **  你看下面對於這些類別的的定義就知道了    **public static final Class OBJECT_CLASS = new Object().getClass();    **  public static final Class STRING_CLASS = "".getClass();    **public static final Class INTEGER_CLASS = new Integer(0).getClass();    **public static final Class LONG_CLASS = new Long(0).getClass();    **public static final Class BOOLEAN_CLASS = new Boolean(true).getClass();    **public static final Class VECTOR_CLASS = new java.util.Vector().getClass();    **/    public Class getTypeByClass(Class cls) {if (cls.isAssignableFrom(Boolean.class)|| cls.isAssignableFrom(boolean.class)) {return PropertyInfo.BOOLEAN_CLASS;} else if (cls.isAssignableFrom(String.class)) {return PropertyInfo.STRING_CLASS;} else if (cls.isAssignableFrom(Integer.class)|| cls.isAssignableFrom(int.class)|| cls.isAssignableFrom(byte.class)|| cls.isAssignableFrom(Byte.class)) {return PropertyInfo.INTEGER_CLASS;} else if (cls.isAssignableFrom(Vector.class)) {return PropertyInfo.VECTOR_CLASS;} else if (cls.isAssignableFrom(Long.class)|| cls.isAssignableFrom(long.class)) {return PropertyInfo.LONG_CLASS;} else {return PropertyInfo.OBJECT_CLASS;}}}

當然這個類已經基本可以滿足大多數不複雜類的調用了。

不過一些嵌套複雜的類型的類仍然可能報序列化的錯誤,在這裡我們將暫時不再深入研究。

有興趣的可以繼續瞭解一下:

他為什麼會報序列化錯誤?

再writeElement的時候

private void writeElement(XmlSerializer writer, Object element, PropertyInfo type, Object marshal)throws IOException{if (marshal != null)((Marshal) marshal).writeInstance(writer, element);else if (element instanceof SoapObject)writeObjectBody(writer, (SoapObject) element);else if (element instanceof KvmSerializable)writeObjectBody(writer, (KvmSerializable) element);else if (element instanceof Vector)writeVectorBody(writer, (Vector) element, type.elementType);elsethrow new RuntimeException("Cannot serialize: " + element);}

很顯然當他沒有Marshal 又不是SoapObject KvmSerializable Vector中的一種類型的時候他就無法序列化了!自然就報錯了!那麼根據這個我們是不是抓住了點什嗎?

SoapSerializationEnvelope中有一個這樣的addMapping方法Marshal

//他的說明是

//Defines a direct mapping from a namespace and name to a java class (and vice versa)

有興趣可以研究一下。


好了!基礎的對象構建傳遞就將到這裡了!

既然有序列化,那麼如何對Ksoap2接收到的服務端資料進行解析呢?敬請期待

下一篇《Android調用WebService系列之KSoap2對象解析》

本文出自 “Arps烙印” 部落格,請務必保留此出處http://laoyin.blog.51cto.com/4885213/1674017

Android調用WebService系列之對象構建傳遞

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.