[转载 ]Android Post请求 RestFull Wcf

2012年9月29日

初学Android,找了个点餐系统来练手,这是倒腾几天的成果。

RestFull Wcf网上有很多资料,但对于我来说还是不太顺利。在使用Android以Post方式请求数据时分别出现过几次404,405错误。现提供解决方法。

  • RestFull Wcf 服务器端。
  1. 服务契约

    需要注意两点,一是必须设置Method为“POST”,必须大写,血的教训啊。二是必须注意BodyStyle的设置,如果参数是多个字符串,则BodyStyle 设置为WebMessageBodyStyle.Bare;如果参数是实体对象,则BodyStyle 设置为WebMessageBodyStyle.WrappedRequest或者WebMessageBodyStyle.Wrapped,并且实体对象和属性必须分别添加DataContract和DataMember特性。

代码如下:

View Code
复制代码
 /// <summary>
    /// 服务契约
    /// </summary>
    [ServiceContract]
    public interface IOrderService
    {
        [OperationContract(Name = "LoginJson")]
        [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Login?account={account}&password={password}")]
        string Login(string account, string password);
        //如果参数是对象,则BodyStyle 必须是WebMessageBodyStyle.Bare
        [OperationContract(Name = "LoginPostJson")]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "LoginPost")]
        string LoginPost(Account account);
        //如果参数是字符串,则BodyStyle 必须是WebMessageBodyStyle.WrappedRequest或者WebMessageBodyStyle.Wrapped
        //[OperationContract(Name = "LoginPostJson")]
        //[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest, UriTemplate = "LoginPost")]
        //string LoginPost(string account, string password);
    }

/// <summary>
    /// 用户信息
    /// </summary>
    [DataContract]
    public class Account
    {
        [DataMember]
        public int id { get; set; }
        [DataMember]
        public string account { get; set; }
        [DataMember]
        public string password { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public string gender { get; set; }
        [DataMember]
        public int permission { get; set; }
        [DataMember]
        public string remark { get; set; }
    }
复制代码

     2.服务实现

    这个很简单了,没什么可说的,直接上代码

View Code
复制代码
/// <summary>
    /// 服务实现
    /// </summary>
    public class OrderService : IOrderService
    {
        public string Login(string account, string password)
        {
            return DataCache.FindAccount(new Account() { account = account, password = password });
        }
        //字符串参数
        //public string LoginPost(string account, string password)
        //{
        //    return DataCache.FindAccount(new Account() { account = account, password = password });
        //}
        //Model参数
        public string LoginPost(Account account)
        {
            if (account == null) return "0";
            return DataCache.FindAccount(new Account() { account = account.account, password = account.password });
        }
    }
复制代码

  3.为了简单,我直接用静态变量存数据,没有用到数据库。也贴一下代码。

View Code
复制代码
/// <summary>
    /// 模拟数据库
    /// </summary>
    class DataCache
    {
        private static List<Account> accounts = new List<Account>() { new Account() { account = "zhansan", password = "password" }, new Account() { account = "lishi", password = "password" } };

        static DataCache()
        {
            Account temp = new Account() { id = 1, account = "a", password = "a", name = "aa", gender = "", permission = 0, remark = "a" };
            accounts.Add(temp);
            temp = new Account() { id = 2, account = "b", password = "b", name = "bb", gender = "", permission = 0, remark = "a" };
            accounts.Add(temp);
        }
        /// <summary>
        /// 查询用户
        /// </summary>
        /// <param name="account"></param>
        /// <returns>不存在则返回“0”,存在则返回id和name</returns>
        public static string FindAccount(Account account)
        {
            string msg = "0";

            Account temp = accounts.Find(e => e.account.Equals(account.account) && e.password.Equals(account.password));
            if (temp != null)
            {
                msg = "";
                msg += "id=" + temp.id;
                msg += ";";
                msg += "name=" + temp.name;
            }
            return msg;
        }

    }
复制代码

  4.开启服务,Hosting方式

View Code
复制代码
class Program
    {
        static void Main(string[] args)
        {
            //开启服务
            using (ServiceHost host = new ServiceHost(typeof(OrderService)))
            {
                host.Open();
                Console.WriteLine("OrderService Started");
                foreach (var item in host.Description.Endpoints)
                {
                    Console.WriteLine("address:" + item.Address.ToString());
                }
                Console.WriteLine("Preess any key to stop service");
                Console.ReadKey();
                host.Close();
            }
        }
    }
复制代码

  5.配置文件

View Code
复制代码
<?xml version="1.0"?>
<configuration>
    <system.serviceModel>
        <services>
            <service name="WirelessOrder_Server.OrderService">
                <endpoint address="" binding="webHttpBinding"  contract="WirelessOrder_Server.IOrderService" behaviorConfiguration="WebHttpBindingBehavior"></endpoint>
                <host>
                    <baseAddresses>
                        <add baseAddress="http://127.0.0.1:45368/OrderService"/>
                    </baseAddresses>
                </host>
            </service>
        </services>
        <behaviors>
            <!--<serviceBehaviors>
                <behavior>
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>-->
            <endpointBehaviors>
                <behavior name="WebHttpBindingBehavior">
                    <webHttp/>
                </behavior>
            </endpointBehaviors>
        </behaviors>
    </system.serviceModel>
    <!--<startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>-->
</configuration>
复制代码

  • Android 客户端

  android Post请求数据以HttpPost请求,以JsonStringer组装json数据,直接贴代码

View Code
复制代码
public class HttpUtil {
    // 基础URL
    public static final String BASE_URL = "http://10.0.2.2:45368/OrderService/";
    private static final String USER_AGENT = "Mozilla/4.5";

    // 获得Get请求对象request
    public static HttpGet getHttpGet(String url) {
        HttpGet request = new HttpGet(url);
        return request;
    }

    // 获得Post请求对象request
    public static HttpPost getHttpPost(String url) {
        HttpPost request = new HttpPost(url);
        return request;
    }

    // 根据路径和参数获得Post请求对象request并
    public static HttpPost getHttpPost(String url, Map<String, String> jsonMap) {
        HttpPost request = new HttpPost(url);

        request.setHeader("Accept", "application/json");
        request.setHeader("Content-Type", "application/json");
        request.setHeader("User-Agent", USER_AGENT);
        if (jsonMap != null) {
            try {
                JSONStringer json = new JSONStringer();
                json.object();
                for (String key : jsonMap.keySet()) {
                    json.key(key).value(jsonMap.get(key));
                }
                json.endObject();

                StringEntity entity = new StringEntity(json.toString(), "UTF-8");
                request.setEntity(entity);
            } catch (JSONException e) {
                e.printStackTrace();
                Log.i("JSONStringer", e.toString());
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                Log.i("StringEntity", e.toString());
            }
        }
        return request;
    }

    // 根据请求获得响应对象response
    public static HttpResponse getHttpResponse(HttpGet request)
            throws ClientProtocolException, IOException {
        HttpResponse response = new DefaultHttpClient().execute(request);
        return response;
    }

    // 根据请求获得响应对象response
    public static HttpResponse getHttpResponse(HttpPost request)
            throws ClientProtocolException, IOException {
        HttpResponse response = new DefaultHttpClient().execute(request);
        return response;
    }

    // 发送Post请求,获得响应查询结果
    public static String queryStringForPost(String url) {
        // 根据url获得HttpPost对象
        HttpPost request = HttpUtil.getHttpPost(url);
        String result = null;
        try {
            // 获得响应对象
            HttpResponse response = HttpUtil.getHttpResponse(request);
            // 判断是否请求成功
            if (response.getStatusLine().getStatusCode() == 200) {
                // 获得响应
                result = EntityUtils.toString(response.getEntity());
                return result;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        }
        return null;
    }

    // 发送Post请求,获得响应查询结果
    public static String queryStringForPost(String url, Map<String, String> jsonMap) {
        // 根据url获得HttpPost对象
        HttpPost request = HttpUtil.getHttpPost(url,jsonMap);
        String result = null;
        try {
            // 获得响应对象
            HttpResponse response = HttpUtil.getHttpResponse(request);
            // 判断是否请求成功
            if (response.getStatusLine().getStatusCode() == 200) {
                // 获得响应
                result = EntityUtils.toString(response.getEntity());
                return result;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        }
        return null;
    }

    // 获得响应查询结果
    public static String queryStringForPost(HttpPost request) {
        String result = null;
        try {
            // 获得响应对象
            HttpResponse response = HttpUtil.getHttpResponse(request);
            // 判断是否请求成功
            if (response.getStatusLine().getStatusCode() == 200) {
                // 获得响应
                result = EntityUtils.toString(response.getEntity());
                return result;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        }
        return null;
    }

    // 发送Get请求,获得响应查询结果
    public static String queryStringForGet(String url) {
        // 获得HttpGet对象
        HttpGet request = HttpUtil.getHttpGet(url);
        String result = null;
        try {
            // 获得响应对象
            HttpResponse response = HttpUtil.getHttpResponse(request);
            // 判断是否请求成功
            if (response.getStatusLine().getStatusCode() == 200) {
                // 获得响应
                result = EntityUtils.toString(response.getEntity());
                return result;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            result = "网络异常!";
            return result;
        }
        return null;
    }
}



//方法调用
// 根据用户名称密码查询
    private String query(String account, String password) {
        // 查询参数
        // String queryString = "account="+account+"&password="+password;
        // url
        // String url = HttpUtil.BASE_URL+"Login?"+queryString;
        // 查询返回结果
        // GET方式请求
        // return HttpUtil.queryStringForGet(url);

        // POST方式请求
        Map<String, String> loginData = new HashMap<String, String>();
        loginData.put("account", account);
        loginData.put("password", password);
        return HttpUtil.queryStringForPost(HttpUtil.BASE_URL + "LoginPost",loginData);

    }
复制代码
原文地址:https://www.cnblogs.com/fx2008/p/2783958.html