WCF服务端与使用HttpClient的Android客户端简单示例

本文通过实例展示了如何创建WCF服务端,包括Contract、Service和Hosting,并配置App.config及Program.cs。同时,详细介绍了Android客户端如何利用HttpClient与WCF服务进行交互,主要涉及HttpClientThread.java、MainActivity.java以及必要的AndroidManifest.xml配置。参考了相关文档,实现Android调用WCF服务的功能。

WCF服务端

Contract
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Web;

namespace Contract
{
    /// <summary>
    /// 服务接口
    /// </summary>
    /// <remarks>
    /// WebInvoke - 指示服务操作在逻辑上就是调用操作,而且可由Web编程模型调用
    /// WebGet - 指示服务操作在逻辑上就是检索操作,而且可由Web编程模型调用
    /// UriTemplate - 用于服务操作的统一资源标识符(URI)模版。URI模版可以将一个URI或一组URI映射到服务操作
    /// Method - 与操作关联的写作方法,默认为 POST
    /// ResponseFormat - 指定从服务操作发出的响应的格式。Xml或Json
    /// BodyStyle - 指定body里面的封装
    /// </remarks>
    [ServiceContract]    
    public interface IWcfService
    {
        /// <summary>
        /// GET - 无参数 - 返回值为字符串数组
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [WebGet(
            ResponseFormat = WebMessageFormat.Json)]
        List<string> GetStudentNames();

        /// <summary>
        /// GET - 无参数 - 返回值为自定义类型的数组
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [WebGet(
            ResponseFormat = WebMessageFormat.Json)]
        List<Student> GetStudents();
             
        /// <summary>
        /// GET - 一个参数 - 返回值为int
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(
            UriTemplate = "GetStudentAge/{name}",   
            //UriTemplate = "GetStudentAge?name={name}",    //默认形式
            ResponseFormat = WebMessageFormat.Json)]
        int GetStudentAge(string name);

        /// <summary>
        /// GET - 多个参数 - 返回值为自定义格式
        /// </summary>
        /// <param name="name"></param>
        /// <param name="birth"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(
            UriTemplate = "CreateStudent/{name}/{birth}/{age}", //UriTemplate中只允许字符串类型的变量
            //UriTemplate = "CreateStudent?name={name}&birth={birth}&age={age}",    //默认形式
            ResponseFormat = WebMessageFormat.Json)]
        Student CreateStudent(string name, string birth, string age);

        /// <summary>
        /// POST - 一个参数 - 返回值为bool
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [OperationContract]
        [WebInvoke(
            UriTemplate = "DeleteStudent",
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.WrappedRequest,
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json)]
        bool DeleteStudent(string name);

        /// <summary>
        /// POST - 多个参数 - 返回值为自定义格式
        /// </summary>
        /// <param name="name"></param>
        /// <param name="birth"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        [OperationContract]
        [WebInvoke(
            UriTemplate = "AddStudent",
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.WrappedRequest,
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json)]
        Student AddStudent(string name, string birth, int age);

        /// <summary>
        /// POST - 自定义格式参数 - 返回值为string
        /// </summary>
        /// <param name="student"></param>
        /// <returns></returns>
        [OperationContract]
        [WebInvoke(
            UriTemplate = "UpdateStudent",
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.WrappedRequest,
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json)]
        string UpdateStudent(Student student);
    }

    [DataContract]
    public class Student 
    {
        private string name;
        [DataMember(Order = 0, Name = "name")]
        public string Name 
        {
            get { return name; }
            set 
            { 
                name = HttpUtility.UrlDecode(value, Encoding.UTF8);
            }
        }

        private string birth;
        [DataMember(Order = 1, Name = "birth")]
        public string Birth
        {
            get { return birth; }
            set { this.birth = value; }
        }

        private int age;
        [DataMember(Order = 1, Name = "age")]
        public int Age
        {
            get { return age; }
            set { this.age = value; }
        }
    }
}
Service
using Contract;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

namespace Service
{
    public class WcfService : IWcfService
    {
        public List<string> GetStudentNames()
        {
            Console.WriteLine();
            Console.WriteLine("GetStudentNames()");

            List<string> results = new List<string>();
            results.Add("zhangsan");
            results.Add("李四");
            results.Add("wangwu");
            return results;
        }

        public List<Student> GetStudents()
        {
            Console.WriteLine();
            Console.WriteLine("GetStudents()");

            List<Student> results = new List<Student>();
            results.Add(new Student() { Name = "zhangsan", Birth = "1955-5-48", Age = 56 });
            results.Add(new Student() { Name = "李四", Birth = "1965-6-48", Age = 46 });
            return results;
        }

        public int GetStudentAge(string name)
        {
            Console.WriteLine();
            Console.WriteLine("GetStudentAge(name)");
            Console.WriteLine();
            Console.WriteLine("name = " + name);

            return 22;
        }

        public Student CreateStudent(string name, string birth, string age)
        {
            Console.WriteLine();
            Console.WriteLine("CreateStudent(name,birth,age)");
            Console.WriteLine();
            Console.WriteLine("name = " + name + ", birth = " + birth + ", age = " + age);

            return new Student()
            {
                Name = name,
                Birth = birth,
                Age = Convert.ToInt32(age)
            };
        }

        public bool DeleteStudent(string name)
        {
            name = HttpUtility.UrlDecode(name, Encoding.UTF8);
            Console.WriteLine();
            Console.WriteLine("DeleteStudent(name)");
            Console.WriteLine();
            Console.WriteLine("name = " + name);

            return true;
        }

        public Student AddStudent(string name, string birth, int age)
        {
            Console.WriteLine();
            Console.WriteLine("AddStudent(name,birth,age)");
            Console.WriteLine();
            Console.WriteLine("name = " + name + ", birth = " + birth + ", age = " + age);

            return new Student()
            {
                Name = name,
                Birth = birth,
                Age = age
            };
        }

        public string UpdateStudent(Student student)
        {
            Console.WriteLine();
            Console.WriteLine("UpdateStudent(student)");
            Console.WriteLine();
            Console.WriteLine("name = " + student.Name + " , birth = " + student.Birth);
            
            return student.Name;
        }
    }
}
Hosting
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp helpEnabled="true"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="webHttpBehavior">
          <serviceMetadata httpGetEnabled="true" httpGetUrl="metadata"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBinding" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="webHttpBehavior" name="Service.WcfService">
        <endpoint address="/" behaviorConfiguration="webHttpBehavior"
          binding="webHttpBinding" bindingConfiguration="webHttpBinding"
          name="WcfService" contract="Contract.IWcfService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8888/service" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <!--保存具体的错误信息到svclog文件中-->
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Warning" propagateActivity="true">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="F:\wcf.svclog" />
    </sharedListeners>
  </system.diagnostics>
</configuration>
Program.cs
using System;
using System.ServiceModel;

namespace Hosting
{
    class Program
    {
        /// <summary>
        /// 采用自托管的方式发布服务
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("---------------------------------------------------------------");

            ServiceHost host = null;
            try
            {
                host = new ServiceHost(typeof(Service.WcfService));

                host.Opened += host_Opened;

                host.Open();

                //公共服务地址
                foreach (var endPoint in host.Description.Endpoints)
                {
                    Console.WriteLine(endPoint.Address.ToString());
                }

                Console.WriteLine("按任意键终止服务!");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.Read();

                if (host != null) 
                {
                    host.Close();
                    host = null;
                }
            }
        }

        static void host_Opened(object sender, EventArgs e)
        {
            Console.WriteLine("Service已经启动");
        }
    }
}

Android客户端

HttpClientThread.java
import android.os.Handler;
import android.widget.TextView;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class HttpClientThread extends Thread {

    private Handler handler;
    private TextView textView;

    private HttpParams httpParams;
    private HttpClient httpClient;

    public HttpClientThread(Handler handler, TextView textView) {
        this.handler = handler;
        this.textView = textView;

        this.httpClient = getHttpClient();
    }

    @Override
    public void run() {
        String result = "";

        String url = "http://192.168.0.192:8888/service/";

        //GET,无参数,返回值为字符串数组
//        result = doHttpClientGet(url + "GetStudentNames");
//        try {
//            JSONArray array = new JSONArray(result);
//            result = "";
//            for (int i=0; i<array.length(); i++) {
//                String str = array.getString(i);
//                result += str + "\n";
//            }
//        } catch (JSONException e) {
//            e.printStackTrace();
//        }

        //GET,无参数,返回值为自定义类型的数组
//        result = doHttpClientGet(url + "GetStudents");
//        result = parseStudentArray(result);

        //GET,一个参数,返回值为整型
//        result = doHttpClientGet(url + "GetStudentAge/张三");
//        result = doHttpClientGet(url + "GetStudentAge?name=张三");//根据服务端的UriTemplate确定

        //GET,多个参数,返回值为自定义格式
//        result = doHttpClientGet(url + "CreateStudent/张三/1982-12-13/23");
//        result = parseStudent(result);

        //POST,一个参数,返回值为布尔值
//        JSONStringer jsonStringer = null;
//        try {
//            jsonStringer = new JSONStringer()
//                    .object()
//                    .key("name").value(URLEncoder.encode("张三", "utf-8"))
//                    .endObject();
//            result = doHttpClientPost(url + "DeleteStudent", jsonStringer);
//        } catch (JSONException e) {
//            e.printStackTrace();
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }

        //POST,多个参数,返回值为自定义类型
//        try {
//            JSONStringer jsonStringer = new JSONStringer()
//                    .object()
//                    .key("name").value("zhangsan")
//                    .key("birth").value("1923-12-34")
//                    .key("age").value(89)
//                    .endObject();
//            result = doHttpClientPost(url + "AddStudent", jsonStringer);
//            result = parseStudent(result);
//        } catch (JSONException e) {
//            e.printStackTrace();
//        }

        //POST,自定义格式参数,返回值为字符串类型
        try {
            JSONStringer jsonStringer = new JSONStringer()
                    .object()
                        .key("student")
                        .object()
                            .key("name").value("lisi")
                            .key("birth").value("2010-4-30")
                        .endObject()
                    .endObject();
            result = doHttpClientPost(url + "UpdateStudent", jsonStringer);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        //显示结果
        final String finalResult = result;
        handler.post(new Runnable() {
            @Override
            public void run() {
                textView.setText(finalResult);
            }
        });
    }

    private String doHttpClientPost(String url, JSONStringer jsonStringer) {
//        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-type", "application/json");

        try {
            if (jsonStringer != null) {
                httpPost.setEntity(new StringEntity(jsonStringer.toString()));
            }

            HttpResponse httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(httpResponse.getEntity());
                return result;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String doHttpClientGet(String url) {
//        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(httpResponse.getEntity());
                return result;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    private HttpClient getHttpClient() {
        httpParams = new BasicHttpParams(); //可不配置

        //设置连接超时、Socket超时、Socket缓存大小
        HttpConnectionParams.setConnectionTimeout(httpParams, 20*1000);
        HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000);
        HttpConnectionParams.setSocketBufferSize(httpParams, 8192);

        //设置重定向,缺省为true
        HttpClientParams.setRedirecting(httpParams, true);

        //设置用户代理
        String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
        HttpProtocolParams.setUserAgent(httpParams, userAgent);

        httpClient = new DefaultHttpClient(httpParams);
        return httpClient;
    }

    /**
     * 解析json字符串为json对象,将json对象转化为student
     * @param json
     * @return
     */
    private String parseStudent(String json) {
        String result = "";
        try {
            JSONObject object = new JSONObject(json);
            Student student = new Student();
            student.setName(object.getString("name"));
            student.setBirth(object.getString("birth"));
            student.setAge(object.getInt("age"));
            result = student.toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 解析json字符串为json数组,将json对象转化为Student
     * @param json
     * @return
     */
    private String parseStudentArray(String json) {
        String result = "";
        try {
            JSONArray jsonArray = new JSONArray(json);
            for (int i=0; i<jsonArray.length(); i++) {
                JSONObject object = jsonArray.getJSONObject(i);
                Student student = new Student();
                student.setName(object.getString("name"));
                student.setBirth(object.getString("birth"));
                student.setAge(object.getInt("age"));
                result += student.toString() + "\n";
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return result;
    }

    public class Student {
        private String name;
        private String birth;
        private int age;

        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }

        public String getBirth() {
            return birth;
        }
        public void setBirth(String birth) {
            this.birth = birth;
        }

        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "Student [name=" + name + ", birth=" + birth + ", age=" + age + "]";
        }
    }
}
MainActivity.java
import android.app.Activity;
import android.os.Handler;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

    private Handler handler = new Handler();

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.text);

        new HttpClientThread(handler, textView).start();
    }	
}
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>

参考文档:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值