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

  • 相关阅读:
    GCC 常用参数 休子的日志 网易博客
    分享:dos2unix 6.0.3 发布
    编写字符串反转函数 小小外星人的技术博客 博客频道 CSDN.NET
    gcc 搜搜百科
    GCC 常用参数 休子的日志 网易博客
    说说IUnitOfWork~DbContext对象的创建应该向BLL层公开
    JS~什么是用心体会,Coder追求的是什么
    基础才是重中之重~值类型和引用类型
    Yslow23条规则
    说说IUnitOfWork~我的IUnitOfWork+Repository架构
  • 原文地址:https://www.cnblogs.com/ArRan/p/2637407.html
Copyright © 2011-2022 走看看