[转载 ]Android Post请求 RestFull Wcf
2012年9月29日
初学Android,找了个点餐系统来练手,这是倒腾几天的成果。
RestFull Wcf网上有很多资料,但对于我来说还是不太顺利。在使用Android以Post方式请求数据时分别出现过几次404,405错误。现提供解决方法。
- RestFull Wcf 服务器端。
- 服务契约
需要注意两点,一是必须设置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); }
虽功未成,亦未敢藏私,众侠诸神通尽录于此,竟成一笈,名葵花宝典,以飨后世。
邮箱:steven9801@163.com
QQ: 48039387
邮箱:steven9801@163.com
QQ: 48039387