zoukankan      html  css  js  c++  java
  • 实例:在Android调用WCF服务(wcf restful)

    实例:在Android调用WCF服务

     

    原文: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。

    复制代码
     1 namespace HttpWcfWeb
    2 {
    3 [ServiceContract(Namespace = "http://services.example.com")]
    4 public interface IVehicleService
    5 {
    6 [OperationContract]
    7 [WebGet(
    8 UriTemplate = "GetPlates",
    9 BodyStyle = WebMessageBodyStyle.WrappedRequest,
    10 ResponseFormat = WebMessageFormat.Json,
    11 RequestFormat = WebMessageFormat.Json)]
    12 IList<string> GetPlates();
    13
    14 [OperationContract]
    15 [WebGet(UriTemplate = "GetVehicle/{plate}",
    16 BodyStyle = WebMessageBodyStyle.WrappedRequest,
    17 ResponseFormat = WebMessageFormat.Json,
    18 RequestFormat = WebMessageFormat.Json)]
    19 Vehicle GetVehicle(string plate);
    20
    21 [OperationContract]
    22 [WebInvoke(
    23 Method = "POST",
    24 UriTemplate = "SaveVehicle",
    25 BodyStyle = WebMessageBodyStyle.WrappedRequest,
    26 ResponseFormat = WebMessageFormat.Json,
    27 RequestFormat = WebMessageFormat.Json)]
    28 void SaveVehicle(Vehicle vehicle);
    29 }
    30 }
    复制代码

    下一步,定义一个用于数据传输的对象,这个对象很简单。

    复制代码
     1 namespace HttpWcfWeb
    2 {
    3 [DataContract]
    4 public class Vehicle
    5 {
    6 [DataMember(Name = "year")]
    7 public int Year
    8 {
    9 get;
    10 set;
    11 }
    12
    13 [DataMember(Name = "plate")]
    14 public string Plate
    15 {
    16 get;
    17 set;
    18 }
    19
    20 [DataMember(Name = "make")]
    21 public string Make
    22 {
    23 get;
    24 set;
    25 }
    26
    27 [DataMember(Name = "model")]
    28 public string Model
    29 {
    30 get;
    31 set;
    32 }
    33 }
    34 }
    复制代码

    现在,我们修改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)->网络接入点,选择正在使用的那一个,填写代理和端口。

     image

    现在,我需要创建Android客户端来调用WCF服务。

    image[1]_3

    在启动过程中,活动(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可以运行。

    android application

  • 相关阅读:
    Windows Azure Web Site (19) Azure Web App链接到VSTS
    Windows Azure Virtual Machine (35) Azure VM通过Linked DB,执行SQL Job
    Azure PowerShell (16) 并行开关机Azure ARM VM
    Windows Azure Virtual Network (12) 虚拟网络之间点对点连接VNet Peering
    Azure ARM (21) Azure订阅的两种管理模式
    Windows Azure Platform Introduction (14) 申请海外的Windows Azure账户
    Azure ARM (20) 将非托管磁盘虚拟机(Unmanage Disk),迁移成托管磁盘虚拟机(Manage Disk)
    Azure ARM (19) 将传统的ASM VM迁移到ARM VM (2)
    Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1)
    Azure Automation (6) 执行Azure SQL Job
  • 原文地址:https://www.cnblogs.com/ArRan/p/2637407.html
Copyright © 2011-2022 走看看