难以将复杂的JSON对象从Android应用程序传递给RESTful服务

时间:2014-06-04 13:53:41

标签: c# android json web-services wcf

我对android的实现有疑问 - > JSON - > RESTful WCF webserive架构。我主要来自基于C#模式的背景,因此很难找到Android架构。我设计C#webservice的方法是拥有一个完整的“模型”命名空间,将所有业务对象(如User,UserProfile,UserSearchCriteria,UserPhoto等)定义为CLR对象。

我已经使用RESTful模型通过WCF公开了我的webservice接口,并结合了我习惯的请求/响应模式。 REST Web方法的一个示例如下。

[OperationContract]
        [WebInvoke(
            Method = "POST",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "/GetSeeds"
            )]
        GetSeedsResponse GetSeeds(GetSeedsRequest request);

响应对象

[DataContract]
    public class GetSeedsResponse
    {
        public GetSeedsResponse(List<Seed> seeds)
        {
            Seeds = seeds;
        }

        [DataMember]
        public List<Seed> Seeds { get; set; }
    }

请求对象

[DataContract]
    public class GetSeedsRequest : BaseRequest
    {
        public GetSeedsRequest(int userId, int numberToTake, int startPosition)
        {
            NumberToTake = numberToTake;
            StartPosition = startPosition;
            UserId = userId;
        }

        [DataMember]
        public int NumberToTake { get; set; }

        [DataMember]
        public int StartPosition { get; set; }

        [DataMember]
        public int UserId { get; set; }
    }

注意:我的所有请求对象都继承自我自己的自定义基本请求对象,它只为它们提供了所有公共标头进行身份验证,如下所示(我不确定这是否是处理身份验证的最佳方式,但它就是我的意思熟悉,所以现在已经这样做了)

[DataContract]
    public abstract class BaseRequest
    {
        [DataMember]
        public Header Header { get; set; }
    }

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.2022")]
    [System.SerializableAttribute]
    [System.Diagnostics.DebuggerStepThroughAttribute]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:MyStory:Web:Services:ServiceModel:Headers")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:MyStory:Web:Services:ServiceModel:Headers", IsNullable=true)]
    public class Header
    {
        public int UserId { get; set; }

        public string SessionToken { get; set; }
    }

到目前为止,我已成功使用AsyncTask后台工作程序中的以下代码从android成功调用RESTful webmethod。

protected ArrayList<Seed> doInBackground(String... params)
    {
        try
        {
            HttpClient client = new DefaultHttpClient();
            HttpPost post = new HttpPost(SERVICE_URI);

            post.setHeader("Accept", "application/json");
            post.setHeader("Content-type", "application/json");

            JSONObject data = new JSONObject();
            data.put("UserId", 1);
            data.put("NumberToTake", 10);
            data.put("StartPosition", 0);

            StringEntity entity = new StringEntity(data.toString());
            post.setEntity(entity);

            HttpResponse response = client.execute(post);
           }
...
}

然后我会寻求提取响应并根据我将定义的android类手动构建一个“Seed”对象,匹配CLR版本的属性,并从JSON响应中手动提取我将使用的索引字段知道哪一个属于哪个属性。

我的问题分为两部分

1)我无法弄清楚如何传递头对象。我试过以下

JSONObject header = new JSONObject();
            header.put("UserId", 1);
            header.put("SessionToken", "");
JSONObject data = new JSONObject();
            data.put("UserId", 1);
            data.put("NumberToTake", 10);
            data.put("StartPosition", 0);
data.put("Header", header);

但是这不能用于通用的“错误请求错误”异常,并且web服务甚至没有进入web方法(我在第1行设置了一个断点,在没有标题的情况下被击中,但是没有被击中当我包含标题时,所以我假设我没有正确理解JSON或者在Request对象中传递嵌入对象的方法

2)我是否正确地采用整个架构方法?对于每个Web服务调用,手动构建数组索引请求和响应似乎非常费力且容易出错。我应该如何构建我的项目,为我的web服务想要接受的所有CLR对象创建匹配的android对象作为参数或作为响应对象返回? JSON是否有更多的功能,我不知道我应该使用它?有了这些请求,我是否需要为我可能进行的每个Web服务调用创建定制的单独AsyncTask对象?我的应用程序将调用大约40种不同的Web方法,这是否意味着在我的代码库中的某个包中保存了40个AsyncTask对象?我正在努力找出设计一个体面大小的应用程序与大量的Web服务交互的“最佳实践”,如果有人有他们可以推荐的任何书籍或教程触及Android项目设计的最佳实践,我的场景的架构那我会非常感激。

对帖子的长度表示道歉

1 个答案:

答案 0 :(得分:0)

将Android端与Windows服务器端分离。我们使用JSON和REST的原因是它们与系统无关。不要担心Windows端的结构。而是关注JSON请求对服务器的作用,并专注于在Android上创建JSON。

首先,获取一个像POSTMan这样的REST客户端,找出REST调用的样子,以及JSON主体的样子。

然后,弄清楚如何让Android发送该主体。

最后,弄清楚如何让Android以编程方式生成JSON主体。对于最后一个,我强烈推荐Gson。它将允许您使用更高级别的对象,而不是手动构建JSON。如果您使用JSON正文更新请求,我将更新此响应以及如何在Gson中生成。

作为旁注,我建议您查看OkHttp而不是Apache HTTP客户端。它功能更强大,功能更强大。这根本不是必需的,但它会让你的生活更轻松。