Adroid與webservice進行實體對象的傳遞

我是半吊子的安卓開發者,之前沒接觸過java的網站開發。因此在開發android應用程序中,首選工具就是VS2010+Eclipse。那麼android開發中與服務器的通訊也理所當然的使用webservice。

        android程序與服務器端的數據交互無非是對象的接收與發送。在網絡中能夠傳遞的除瞭值類型還有json和xml。估計剛學習android開發的同學也和我當初一樣,遇到過這個難題——如何安全順暢的在客戶端與服務器端進行數據傳遞。

        先說說使用到第三方類庫。android項目中使用瞭ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar,這個類庫如何使用大傢可以谷哥度娘哈,網上一大堆!在webservice項目中使用瞭Newtonsoft.Json.dll,這個是個新鮮玩意,稍後講到如何使用!  
       1、值類型的傳遞

             值類型通過ksoap可以直接進行傳遞,這裡就不多說瞭!利用ksoap,值類型的變量即可作參數,也可以當作返回值。

       2、在android端獲取服務器端的數據列表。

             先說說項目結構。webservice的項目中我建立瞭Model層,Android中建立瞭Model的包。這兩個是對應的,每個model的字段名稱必須一致。就拿圖片作為對象來說吧。

             Webservices中ImageModel.cs

           

[csharp] 
public class ImageModel 
   { 
       public string Id { get; set; } 
 
       public string Name { get; set; } 
 
       public string Path { get; set; } 
 
       public string FId { get; set; } 
 
       public string FIdType { get; set; } 
 
       public string FileExtension { get; set; } 
 
       public string FileSize { get; set; } 
 
       public string Adder { get; set; } 
 
       public string AddTime { get; set; } 
   } 

        在C#中可以將實體對象直接序列化為xml進行傳遞。

[csharp] 
[WebMethod(Description = "獲取單個圖片")] 
public ImageModel GetImageModel(string id) 

    return new ImageModel(); 

 
[WebMethod(Description = "獲取圖片列表")] 
public List<ImageModel> GetImageModels(string id) 

    return new List<ImageModel>(); 

       在調用webservice時,這兩個方法的返回值都以標準的xml形式展現。大傢可以發佈後自己用瀏覽器測試。

        在android端,以下代碼為瞭方便大傢使用,我將幾個類中的方法進行瞭整合,大傢弄明白後可以自己進行重構。

[java] 
public static ArrayList<ImageModel> getImageModels(String id) { 
        String methodName = "GetImageModels"; 
        PropertyInfo[] propertyInfos = new PropertyInfo[1]; 
        propertyInfos[0] = new PropertyInfo(); 
        propertyInfos[0].setName("id"); 
        propertyInfos[0].setValue(id); 
 
        SoapObject imgSoapObject = (SoapObject) getObject( 
                methodName, propertyInfos); 
        ArrayList<ImageModel> models=new ArrayList<ImageModel>(); 
            if (imgSoapObject != null) { 
                for (int i = 0; i < imgSoapObject.getPropertyCount(); i++) { 
                    SoapObject imgObject = (SoapObject) imgSoapObject 
      .getProperty(i); 
    ImageModel imgModel = new ImageModel(); 
    imgModel.Id = WebServiceParameter.getPropertyString(imgObject, 
      "Id"); 
    imgModel.Name = WebServiceParameter.getPropertyString( 
      imgObject, "Name"); 
    imgModel.Path = WebServiceParameter.fileUrl 
      + WebServiceParameter.getPropertyString(imgObject, 
        "Path");                    models.add(imgModel); 
                } 
            } 
         
        return models; 
    } 
 
    /**
     * webservices命名空間
     */ 
    public static final String NAMESPACE = "https://gl.ejiang.org/"; 
 
    /**
     * 頁面名稱
     */ 
    public static String pageName = "BoilerService.asmx"; 
 
    /**
     * webservices地址
     */ 
    public static String webserviceUrl = "https://888.88.88.888:9002/"; 
     
    /**
     * 用webservice返回遠程數據庫數據
     * 
     * @param methodName
     *            方法名
     * @param propertyInfos
     *            參數
     * @return
     */ 
    public static Object getObject(String methodName, 
            PropertyInfo[] propertyInfos) { 
        Object object = GetWebServiceData( 
                NAMESPACE, webserviceUrl + "/" + pageName, 
                NAMESPACE + methodName, methodName, 
                propertyInfos); 
        return object; 
    } 
     
    private static  Object GetWebServiceData(String iNameSpace, 
            String iWebserviceURL, String iSoapAction, String iMethodName, 
            PropertyInfo[] iPropertyInfo) { 
        Object result = null; 
        try { 
            SoapObject rpc = new SoapObject(iNameSpace, iMethodName); 
            for (int i = 0; i < iPropertyInfo.length; i++) { 
                rpc.addProperty(iPropertyInfo[i]); 
            } 
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( 
                    SoapEnvelope.VER11); 
            envelope.bodyOut = rpc; 
 
            envelope.dotNet = true; 
            envelope.setOutputSoapObject(rpc); 
            HttpTransportSE ht = new HttpTransportSE(iWebserviceURL, 5000); 
            ht.debug = true; 
            ht.call(iSoapAction, envelope); 
            result = envelope.getResponse(); 
        } catch (Exception e) { 
            Toast.makeText(CrashApplication.getContext(), "連接服務器失敗,請檢查網絡設置!", Toast.LENGTH_SHORT) 
            .show(); 
        } 
         
        return result; 
    } 
     

       以上代碼實現瞭在android端獲取圖片列表。

       3、將android端的信息上傳至服務器。這個功能著實折騰瞭我好長時間!最初打算用xml的方式進行傳遞,即將每個字段以及字段的值按照xml的方式進行手動鏈接,但是考慮到所做的項目包含二十多個報告,每個報告有幾十個字段,工作量太大且代碼臃腫!後來打算用json的方式,java中對json數據格式操作相當方便。但遇到瞭同樣的問題,在webservice端需要對json進行解析,如果手動解析,那工作量可想而知。本人呢也確實比較懶,然後就搜索瞭大量的資料,找到瞭Newtonsoft.Json.dll這個類庫,它支持將json直接解析為實體對象。至此,這個問題才算解決。

            首先還是要確保android端和webservice端的model層結構一致!在上面的代碼中,已經貼出瞭webservice端的ImageModel代碼,下面是android端的ImageModel。

         

[java] 
import org.json.JSONException; 
import org.json.JSONObject; 
 
public class ImageModel { 
    public String Id=""; 
    public String Name=""; 
    public String Path=""; 
    public String FId=""; 
    public String FIdType=""; 
    public String FileExtension=""; 
    public String FileSize=""; 
    public String Adder=""; 
    public String AddTime=""; 
 
    public static String ConvertToJson(ImageModel model) { 
        String jsonStr = ""; 
        JSONObject modelJsonObject = new JSONObject(); 
        try { 
            modelJsonObject.put("Id", model.Id); 
            modelJsonObject.put("Name", model.Name); 
            modelJsonObject.put("Path", model.Path); 
            modelJsonObject.put("FId", model.FId); 
            modelJsonObject.put("FIdType", model.FIdType); 
            modelJsonObject.put("FileExtension", model.FileExtension); 
            modelJsonObject.put("FileSize", model.FileSize); 
            modelJsonObject.put("Adder", model.Adder); 
            modelJsonObject.put("AddTime", model.AddTime); 
            jsonStr = modelJsonObject.toString(); 
        } catch (JSONException e) { 
            e.printStackTrace(); 
        } 
        return jsonStr; 
    } 

ConvrtToJson的主要作用就是將對象轉換為Json,以便於在網絡中傳輸。

android端進行數據的添加代碼:

[java]
/**
 * 將圖片信息添加至遠程數據庫(報告)
 * 
 * @param imageModel
 * @return
 */ 
public static Boolean addImage(ImageModel imageModel) { 
    boolean result = false; 
    String modelJson = ImageModel.ConvertToJson(imageModel); 
    if (modelJson != null) { 
        String methodNameString = "AddImage"; 
        PropertyInfo[] propertyInfos = new PropertyInfo[1]; 
        propertyInfos[0] = new PropertyInfo(); 
        propertyInfos[0].setName("modelJson"); 
        propertyInfos[0].setValue(modelJson); 
        Object flag = WebServiceParameter.getObject( 
                methodNameString, propertyInfos); 
        result = WebServiceParameter.getPropertyValue(flag, false); 
    }  
 
    return result; 

WebServiceParameter.getObject這個方法是ksoap的一次封裝,大傢可參考上面的代碼自己寫。

webservice端解析由android客戶端傳送的json:

[csharp] 
/// <summary> 
       /// 添加附件 
       /// </summary> 
       /// <param name="modelJson"></param> 
       /// <returns></returns> 
       public static bool AddImage(string modelJson) 
       { 
           bool result = false; 
           JsonSerializer jsonSerializer = new JsonSerializer(); 
           StringReader strReader = new StringReader(modelJson); 
           ImageModel model = (ImageModel)jsonSerializer.Deserialize(new JsonTextReader(strReader), typeof(ImageModel)); 
           string strSql = @"insert into pictures_list 
                              ( 
                                fid, 
                                fid_type,  
                               image_url, 
                               file_name, 
                               file_layout, 
                               file_size,  
                               add_men, 
                               add_time) 
                               values 
                               ( 
                               :fid,  
                               :fid_type, 
                               :image_url, 
                               :file_name, 
                               :file_layout, 
                               :file_size, 
                               :add_men, 
                               :add_time)"; 
           OracleParameter[] Parameter = 
               { 
                    new OracleParameter(":fid", OracleDbType.Number, 11), 
                    new OracleParameter(":fid_type", OracleDbType.Number, 11), 
                    new OracleParameter(":image_url", OracleDbType.VarChar, 100), 
                    new OracleParameter(":file_name", OracleDbType.VarChar, 100), 
                    new OracleParameter(":file_layout", OracleDbType.VarChar, 100), 
                    new OracleParameter(":file_size", OracleDbType.VarChar, 100), 
                    new OracleParameter(":add_men", OracleDbType.VarChar, 100), 
                    new OracleParameter(":add_time", OracleDbType.Date) 
               }; 
           Parameter[0].Value = Convert.ToString(model.FId); 
           Parameter[1].Value = Convert.ToString(model.FIdType); 
           Parameter[2].Value = Convert.ToString(model.Path); 
           Parameter[3].Value = Convert.ToString(model.Name); 
           Parameter[4].Value = Convert.ToString(model.FileExtension); 
           Parameter[5].Value = Convert.ToString(model.FileSize); 
           Parameter[6].Value = Convert.ToString(model.Adder); 
           Parameter[7].Value = DateTime.Now; 
           int mm = EJiang.Common.DirectDbHelperOracle.ExecuteSql(strSql, Parameter); 
           if (mm > 0) 
           { 
               result = true; 
           } 
           else 
           { 
               result = false; 
           } 
 
           return result; 
       } 

JsonSerializer jsonSerializer = new JsonSerializer();

StringReader strReader = new StringReader(modelJson);

ImageModel model = (ImageModel)jsonSerializer.Deserialize(new JsonTextReader(strReader), typeof(ImageModel));

利用jsonserializer這個類庫直接將json轉換為ImageModel。很方便吧!

 

       大傢如果有更好的方法,可以分享出來!這是8月份寫的,今天檢查代碼又看到瞭,當時自己耗費瞭好長時間,因此分享出來,供大傢參考,少走彎路!如果有錯誤和疏忽之處,望大傢不吝指教!

You May Also Like