您的位置:首页 > 移动开发 > Android开发

Android与webservice进行实体对象的传递

2013-07-10 17:21 316 查看
我是半吊子的安卓开发者,之前没接触过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

[csharp] view
plaincopy

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] view
plaincopy

[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] view
plaincopy

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。

[java] view
plaincopy

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] view
plaincopy

/**

* 将图片信息添加至远程数据库(报告)

*

* @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] view
plaincopy

/// <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。很方便吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: