[翻译]实例:在Android调用WCF服务
2011-12-16 17:16
639 查看
原文:http://fszlin.dymetis.com/post/2010/05/10/Comsuming-WCF-Services-With-Android.aspx
在移动设备中,使用XML传输可能会消耗更多的资源,Android没有提供任何组件来直接调用WCF,但是我们可以通过第三方的包(例如:org.apache.http,org.json)来相对简单的调用REST形式的WCF服务。
本文将演示如何创建REST形式的WCF服务和在Android上如何调用服务。
第一步,创建一个包含两个GET操作和一个POST操作的Service Contract。由于是通过JSON对象传输数据,这里需要指定Request和Response的数据格式为JSON。为了支持多个参数,还需要设置BodyStyle为WrappedRequest。
下一步,定义一个用于数据传输的对象,这个对象很简单。
现在,我们修改web.config文件,发布WCF服务。
由于VS内置的开发服务器只能处理来自本机的请求,所以需要把服务部署到IIS。
另外,如果你在URL中使用主机名(比如:机器名)的话,你也许还需要在设备或模拟器中设置DNS,这样才可以解析主机名。方法是,进入“系统设置(Setting)”->无线网络设置(Wireless Control)->网络接入点,选择正在使用的那一个,填写代理和端口。
![](http://images.cnblogs.com/cnblogs_com/yiway/201112/201112161713026704.png)
现在,我需要创建Android客户端来调用WCF服务。
![](http://images.cnblogs.com/cnblogs_com/yiway/201112/20111216171303183.png)
在启动过程中,活动(Activity)调用IVehicleService.GetPlates方法填充Spinner。
当Load Vehicle按钮点击时,通过调用IVehicleService.GetVehicle方法得到Vehicle对象并填充到EditText中。
点击Save按钮时,将数据包装并提交到IVehicleService.SaveVehicle方法。
在数据保存或者Activity被恢复(resumed)的时候会调用refreshVehicles方法,它向WCF服务发送一个Get请求,得到一个由JSON字符串表达的数据对象。
onLoadVehicleClick 方法处理Load Vehicle 点击事件,和refreshVehicles 方法相似,它发送一个GET请求到WCF服务,通过plate number得到一个vehicle对象,但区别在于,它在结果处理中使用了JSONObject 转换,就像直接从WCF服务中拿到的vehicle对象一样。
当Save按钮点击时,调用onSaveVehicleClick 方法。这个方法中简单的将所有的文本字段的值放入一个JSONObject对象,然后提交(POST)给WCF服务。注意所有的数据包装进了一个叫vehicle的对象,WCF收到后,会将其作为名称为vehicle的参数。
最后,在AndroidManifest.xml中添加Internet的访问权限。
DEMO可以运行。
![](http://images.cnblogs.com/cnblogs_com/yiway/201112/201112161713043347.png)
在移动设备中,使用XML传输可能会消耗更多的资源,Android没有提供任何组件来直接调用WCF,但是我们可以通过第三方的包(例如:org.apache.http,org.json)来相对简单的调用REST形式的WCF服务。
本文将演示如何创建REST形式的WCF服务和在Android上如何调用服务。
第一步,创建一个包含两个GET操作和一个POST操作的Service Contract。由于是通过JSON对象传输数据,这里需要指定Request和Response的数据格式为JSON。为了支持多个参数,还需要设置BodyStyle为WrappedRequest。
namespace HttpWcfWeb { [ServiceContract(Namespace = "http://services.example.com")] public interface IVehicleService { [OperationContract] [WebGet( UriTemplate = "GetPlates", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] IList<string> GetPlates(); [OperationContract] [WebGet(UriTemplate = "GetVehicle/{plate}", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] Vehicle GetVehicle(string plate); [OperationContract] [WebInvoke( Method = "POST", UriTemplate = "SaveVehicle", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] void SaveVehicle(Vehicle vehicle); } }
下一步,定义一个用于数据传输的对象,这个对象很简单。
namespace HttpWcfWeb { [DataContract] public class Vehicle { [DataMember(Name = "year")] public int Year { get; set; } [DataMember(Name = "plate")] public string Plate { get; set; } [DataMember(Name = "make")] public string Make { get; set; } [DataMember(Name = "model")] public string Model { get; set; } } }
现在,我们修改web.config文件,发布WCF服务。
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="httpBehavior"> <webHttp /> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> <services> <service name="HttpWcfWeb.VehicleService"> <endpoint address="" behaviorConfiguration="httpBehavior" binding="webHttpBinding" contract="HttpWcfWeb.IVehicleService" /> </service> </services> </system.serviceModel>
由于VS内置的开发服务器只能处理来自本机的请求,所以需要把服务部署到IIS。
另外,如果你在URL中使用主机名(比如:机器名)的话,你也许还需要在设备或模拟器中设置DNS,这样才可以解析主机名。方法是,进入“系统设置(Setting)”->无线网络设置(Wireless Control)->网络接入点,选择正在使用的那一个,填写代理和端口。
![](http://images.cnblogs.com/cnblogs_com/yiway/201112/201112161713026704.png)
现在,我需要创建Android客户端来调用WCF服务。
![](http://images.cnblogs.com/cnblogs_com/yiway/201112/20111216171303183.png)
在启动过程中,活动(Activity)调用IVehicleService.GetPlates方法填充Spinner。
当Load Vehicle按钮点击时,通过调用IVehicleService.GetVehicle方法得到Vehicle对象并填充到EditText中。
点击Save按钮时,将数据包装并提交到IVehicleService.SaveVehicle方法。
public class MainActivity extends Activity { private final static String SERVICE_URI = "http://lt0.studio.entail.ca:8080/VehicleService.svc"; private Spinner plateSpinner; private EditText makeEdit; private EditText plateEdit; private EditText yearEdit; private EditText modelEdit; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); plateSpinner = (Spinner)findViewById(R.id.plate_spinner); makeEdit = (EditText)findViewById(R.id.make_edit); plateEdit = (EditText)findViewById(R.id.plate_edit); yearEdit = (EditText)findViewById(R.id.year_edit); modelEdit = (EditText)findViewById(R.id.model_edit); } @Override public void onResume() { super.onResume(); // Invoke IVehicleService.GetPlates and populate plateSpinner refreshVehicles(); } }
在数据保存或者Activity被恢复(resumed)的时候会调用refreshVehicles方法,它向WCF服务发送一个Get请求,得到一个由JSON字符串表达的数据对象。
private void refreshVehicles() { try { // Send GET request to <service>/GetPlates HttpGet request = new HttpGet(SERVICE_URI + "/GetPlates"); request.setHeader("Accept", "application/json"); request.setHeader("Content-type", "application/json"); DefaultHttpClient httpClient = new DefaultHttpClient(); HttpResponse response = httpClient.execute(request); HttpEntity responseEntity = response.getEntity(); // Read response data into buffer char[] buffer = new char[(int)responseEntity.getContentLength()]; InputStream stream = responseEntity.getContent(); InputStreamReader reader = new InputStreamReader(stream); reader.read(buffer); stream.close(); JSONArray plates = new JSONArray(new String(buffer)); // Reset plate spinner ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); for (int i = 0; i < plates.length(); ++i) { adapter.add(plates.getString(i)); } plateSpinner.setAdapter(adapter); } catch (Exception e) { e.printStackTrace(); } }
onLoadVehicleClick 方法处理Load Vehicle 点击事件,和refreshVehicles 方法相似,它发送一个GET请求到WCF服务,通过plate number得到一个vehicle对象,但区别在于,它在结果处理中使用了JSONObject 转换,就像直接从WCF服务中拿到的vehicle对象一样。
public void onLoadVehicleClick(View button) { try { // Send GET request to <service>/GetVehicle/<plate> DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet request = new HttpGet(SERVICE_URI + "/GetVehicle/" + plateSpinner.getSelectedItem()); request.setHeader("Accept", "application/json"); request.setHeader("Content-type", "application/json"); HttpResponse response = httpClient.execute(request); HttpEntity responseEntity = response.getEntity(); // Read response data into buffer char[] buffer = new char[(int)responseEntity.getContentLength()]; InputStream stream = responseEntity.getContent(); InputStreamReader reader = new InputStreamReader(stream); reader.read(buffer); stream.close(); JSONObject vehicle = new JSONObject(new String(buffer)); // Populate text fields makeEdit.setText(vehicle.getString("make")); plateEdit.setText(vehicle.getString("plate")); modelEdit.setText(vehicle.getString("model")); yearEdit.setText(vehicle.getString("year")); } catch (Exception e) { e.printStackTrace(); } }
当Save按钮点击时,调用onSaveVehicleClick 方法。这个方法中简单的将所有的文本字段的值放入一个JSONObject对象,然后提交(POST)给WCF服务。注意所有的数据包装进了一个叫vehicle的对象,WCF收到后,会将其作为名称为vehicle的参数。
public void onSaveVehicleClick(View button) { try { Editable make = makeEdit.getText(); Editable plate = plateEdit.getText(); Editable model = modelEdit.getText(); Editable year = yearEdit.getText(); boolean isValid = true; // Data validation goes here if (isValid) { // POST request to <service>/SaveVehicle HttpPost request = new HttpPost(SERVICE_URI + "/SaveVehicle"); request.setHeader("Accept", "application/json"); request.setHeader("Content-type", "application/json"); // Build JSON string JSONStringer vehicle = new JSONStringer() .object() .key("vehicle") .object() .key("plate").value(plate) .key("make").value(make) .key("model").value(model) .key("year").value(Integer.parseInt(year.toString())) .endObject() .endObject(); StringEntity entity = new StringEntity(vehicle.toString()); request.setEntity(entity); // Send request to WCF service DefaultHttpClient httpClient = new DefaultHttpClient(); HttpResponse response = httpClient.execute(request); Log.d("WebInvoke", "Saving : " + response.getStatusLine().getStatusCode()); // Reload plate numbers refreshVehicles(); } } catch (Exception e) { e.printStackTrace(); } }
最后,在AndroidManifest.xml中添加Internet的访问权限。
<uses-permission android:name="android.permission.INTERNET" />
DEMO可以运行。
![](http://images.cnblogs.com/cnblogs_com/yiway/201112/201112161713043347.png)
相关文章推荐
- [翻译]实例:在Android调用WCF服务
- [转]实例:在Android调用WCF服务
- 实例:在Android调用WCF服务
- 实例:在Android调用WCF服务(wcf restful)
- Android Service AIDL 远程调用服务之简单音乐播放实例
- jQuery ajax调用WCF服务实例
- 一步一个脚印学习WCF系列之WCF概要—WCF服务的创建与调用HelloWorld实例,通过配置文件方式(六)
- WCF并发(Concurrency)的本质:同一个服务实例上下文(InstanceContext)同时处理多个服务调用请求
- Xamarin.Android 入门实例(2)之实现WCF 寄宿于IIS 的Web服务提供
- jQuery ajax调用WCF服务实例
- 简单音乐播放实例的实现,Android Service AIDL 远程调用服务
- C# WCF简单实例 出错:调用方未由服务进行身份验证
- WCF并发(Concurrency)的本质:同一个服务实例上下文(InstanceContext)同时处理多个服务调用请求(转)
- Android上使用ksoap2支持Web Service服务调用实例
- android 远程调用.NET WCF服务
- Android调用WCF服务
- WCF热门问题编程示例(2)多个实例调用一个WCF服务操作,需要等待服务响应吗
- Android调用RESTful WCF服务
- WCF热门问题编程示例(2)多个实例调用一个WCF服务操作,需要等待服务响应吗
- 一个Android客户端,调用WCF服务获取数据