第十五章:Android 调用WebService(.net平台)

什么是webservice?java

Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可以使用开放的XML标准通用标记语言下的一个子集)标准描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操做的应用程序。Web   Service所使用的是Internet上统1、开放的标准,如HTTP、XML、SOAP(简单对象访问协议)、WSDL(webservice描述语言)等,因此Web   Service能够在任何支持这些标准的环境(Windows,Linux)中使用。(说白了,webService就像是一个方法,只不过不是你本身写的,并且是跨语言、跨平台的。咱们只须要调用这个方法得到返回结果便可。至于webservice怎么运行的与调用端是无关的,也不须要知道)android

注:SOAP协议(Simple   Object   Access   Protocal,简单对象访问协议),它是一个用于分散和分布式环境下网络信息交换的基于XML的通信协议。在此协议下,软件组件或应用程序可以经过标准的HTTP协议进行通信。它的设计目标就是简单性和扩展性,这有助于大量异构程序和平台之间的互操做性,从而使存在的应用程序可以被普遍的用户访问。web

 

为何要使用webservice?编程

方便而且开放。你们都知道,在手机上的cpu和内存等条件是颇有限的,尤为是处理一些大数据等易耗损资源的操做都会很是吃力甚至根本就不行。所以,将这一部分的处理交给服务器端,让服务器来处理这些数据。那么在服务器端咱们就能够实现一个webservice让咱们在客户端来调用,返回咱们须要的数据便可。 服务器

 

何时使用webservice?网络

只要是数据交换均可以使用。可是对webservice的优劣要有认识:app

优势:编程语言

  1. 跨平台、跨语言;
  2. SOAP协议是基于XML和HTTP这些业界的标准的,获得了全部的重要公司的支持。
  3. 因为使用了SOAP,数据是以ASCII文本的方式而非二进制传输,调试很方便;而且因为这样,它的数据容易经过防火墙,不须要防火墙为了程序而单独开一个“漏洞”。
  4. WebService实现的技术难度要比CORBA和DCOM小得多。
  5. 要实现B2B集成,EDI比较完善与比较复杂;而用WebService则能够低成本的实现,小公司也能够用上。
  6. 在C/S的程序中,WebService能够实现网页无总体刷新的与服务器打交道并取数。

缺点:分布式

  1. WebService使用了XML对数据封装,会形成大量的数据要在网络中传输。
  2.  WebService规范没有规定任何与实现相关的细节,包括对象模型、编程语言,这一点,它不如CORBA 。

 

怎么使用webservice?(整个过程咱们用一个获取手机号归属地的例子来讲明)ide

要使用webservice就必须知道webservice的接口文档,即WSDL(webservice描述服务)。那么,WSDL究竟长成什么样子呢?

下面我给出了一个连接:(该连接打开就是一个WSDL)

http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl

打开后以下图所示:(未显示完整)

家一看就傻眼了吧,怎么多的信息,到底哪些是咱们须要的呢?

其实,咱们调用webservice只须要三个数据便可:命名空间、方法名称(包括方法名和参数类型)、根节点。

那么WSDL上对应的数据在哪里呢?

根节点便是上面给出的连接去掉“?wsdl”:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx

命名空间、方法名称(包括方法名和参数类型)在下图中依次为从上到下,从左到右。

 

好了,知道了这些。咱们就能够开始开工了。

首先,咱们须要下载一个ksoap2jar包,它是咱们调用webservice的工具类,在此给出一个下载地址:http://download.csdn.net/detail/af74776/7735251

下载好jar包后导入进项目中(先复制到libs文件夹下,点击jar包,单击右键,选择build path ,而后选择add External Archives。而后,单击工程项目,单击右键,选择build path ,再选择configure build pathxxxxx。在弹出的对话框的右侧,选择Order and Export选项卡。在刚刚添加的ksoap2 jar包前打钩,而后选择ok便可)

以下:

成功导入包后,即可开始编写代码了(哎,直接上代码吧。代码上有详细的注解):

布局文件activity_web_service.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingLeft="5dip"
    android:paddingRight="5dip"
    android:paddingTop="5dip" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="手机号码(段):" />

    <EditText
        android:id="@+id/phone_sec"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="例如:1398547"
        android:inputType="textPhonetic"
        android:singleLine="true" />

    <Button
        android:id="@+id/query_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:text="查询" />

    <TextView
        android:id="@+id/result_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical" />

</LinearLayout>
View Code

WebServiceActivity.java:

package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
//import org.ksoap2.transport.AndroidHttpTransport;
import org.ksoap2.transport.HttpTransportSE;


public class WebServiceActivity extends Activity {
    private EditText phoneSecEditText;
    private TextView resultView;
    private Button queryButton;
    String result;
    private String phoneSec;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_service);
        phoneSecEditText = (EditText) findViewById(R.id.phone_sec);
        resultView = (TextView) findViewById(R.id.result_text);
        queryButton = (Button) findViewById(R.id.query_btn);

        queryButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                phoneSec = phoneSecEditText.getText().toString().trim();
                // 简单判断用户输入的手机号码(段)是否合法
                if ("".equals(phoneSec) || phoneSec.length() < 7) {
                    // 给出错误提示
                    phoneSecEditText.setError("您输入的手机号码(段)有误!");
                    phoneSecEditText.requestFocus();
                    // 将显示查询结果的TextView清空
                    resultView.setText("");
                    return;
                }
                //Android4.0之后便不能够在主线程中访问网络了,所以要新开线程
                Runnable r = new NetWorkHandler();
                Thread thread = new Thread(r);
                thread.start();
                // 因为网络链接须要必定时间,为了在主界面上进行网络信息的展示,暂时用sleep()方法简单实现,使主线程等待网络信息读取完成。
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (result != null) {
                    resultView.setText(result);
                }
            }

        });

    }

    /**
     * 手机号段归属查询
     * 
     * @param phoneSec手机号段
     */
    private void getRemoteInfo(String phoneSec) {
        // 命名空间
        String nameSpace = "http://WebXml.com.cn/";
        // 调用的方法名称
        String methodName = "getMobileCodeInfo";
        // EndPoint
        String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
        // SOAP Action 为命名空间+方法名称
        String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";

        // 指定WebService的命名空间和调用的方法名
        SoapObject rpc = new SoapObject(nameSpace, methodName);

        // 设置需调用WebService接口须要传入的两个参数mobileCode、userId
        rpc.addProperty("mobileCode", phoneSec);
        rpc.addProperty("userId", "");

        // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER12);

        envelope.bodyOut = rpc;
        // 设置是否调用的是dotNet开发的WebService
        envelope.dotNet = true;
        // 等价于envelope.bodyOut = rpc;
        envelope.setOutputSoapObject(rpc);

        HttpTransportSE transport = new HttpTransportSE(endPoint);
        try {
            // 调用WebService
            transport.call(soapAction, envelope);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("调用webservice异常");
        }

        // 获取返回的数据
        SoapObject object = (SoapObject) envelope.bodyIn;
        if (object != null)
            // 获取返回的结果
            result = object.getProperty(0).toString();
        else {
            System.out.println("object为空");
        }
    }

    private class NetWorkHandler implements Runnable {

        @Override
        public void run() {
            getRemoteInfo(phoneSec);

        }

    }
}
View Code

注意:千万不要忘记在清单文件中加上权限<uses-permission android:name="android.permission.INTERNET" />

固然,从程序严谨的角度来说最好再加上手机是否连网的判断。

该例子在wifi环境下测试无异常,不保证在使用流量的状况下也正常。最后的效果以下图:

相关文章
相关标签/搜索