Android與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,這個是個新鮮玩意,稍後講到如何使用!  這兩個類庫下載地址http://download.csdn.net/detail/wuwo333/4634813

       1、值類型的傳遞

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

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

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

             Webservices中ImageModel.cs

            

 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進行傳遞。

        [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端,以下代碼爲了方便大家使用,我將幾個類中的方法進行了整合,大家弄明白後可以自己進行重構。

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 = "http://gl.ejiang.org/";

	/**
	 * 頁面名稱
	 */
	public static String pageName = "BoilerService.asmx";

	/**
	 * webservices地址
	 */
	public static String webserviceUrl = "http://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。

          

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端進行數據的添加代碼:

	/**
	 * 將圖片信息添加至遠程數據庫(報告)
	 * 
	 * @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:

 /// <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月份寫的,今天檢查代碼又看到了,當時自己耗費了好長時間,因此分享出來,供大家參考,少走彎路!如果有錯誤和疏忽之處,望大家不吝指教!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章