当前位置 : 主页 > 网页制作 > Nodejs >

WebService之Soap协议数据解析篇

来源:互联网 收集:自由互联 发布时间:2021-06-24
还是老规矩先上效果图! 相信大家很多人应该知道Web service是一种服务导向架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作。根据W3C的定义,Web服

还是老规矩先上效果图!

相信大家很多人应该知道Web service是一种服务导向架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作。根据W3C的定义,Web服务(Web
service)应当是一个软件系统,用以支持网络间不同机器的互动操作。网络服务通常是许多应用程序接口(API)所组成的,它们透过网络,例如Internet的远程服务器端,执行客户所提交服务的请求。无论定义还是实现,WEB服务过程中会由服务器提供一个机器可读的描述以辨识服务器所提供的WEB服务。另外,虽然WSDL不是SOAP服务端点的必要条件,但目前基于Java的主流WEB服务开发框架往往需要WSDL实现客户端的源代码生成。一些工业标准化组织就在WEB服务定义中强制包含SOAP和WSDL。
如图所示


Soap协议

SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。它有三个主要方面:XML-envelope为描述信息内容和如何处理内容定义了框架,将程序对象编码成为XML对象的规则,执行远程过程调用(RPC)的约定。SOAP可以运行在任何其他传输协议上。例如,你可以使用 SMTP,即因特网电子邮件协议来传递SOAP消息,这可是很有诱惑力的。在传输层之间的头是不同的,但XML有效负载保持相同。

Web Service 希望实现不同的系统之间能够用“软件-软件对话”的方式相互调用,打破了软件应用、网站和各种设备之间的格格不入的状态,实现“基于Web无缝集成”的目标。

WSDL

Web Service描述语言WSDL 就是用机器能阅读的方式提供的一个正式描述文档而基于XML的语言,用于描述Web
Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。

UDDI

一个用来发布和搜索WEB服务的协议,应用程序可借由此协议在设计或运行时找到目标WEB服务。

这些标准由这些组织制订:W3C负责XML、SOAP及WSDL;OASIS负责UDDI等
概念就介绍到这里吗,如果您还没熟悉没事,可以直接进入柳峰大神的博客去详细看WebService入门介绍,这里不啰嗦了!
下面进准备工作首先是URL
http://139.129.20.80:8088/WebSerive/CRMWebService.asmx?op=GetArea
点击进入就可以调用了,然后界面如下,相信大家看到这样的数据格式应该并不是很陌生吧!

(http://www.voidcn.com/article/p-raonnfgd-bpq.html)

上图分析可以得出最外面是dList数组然后里面是一个javabean类,因此我们需要创建一个dListBean实体

到这里我们就要准备开车了!别急嘛哈哈!

首先下载一个jar包ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar,由于上传不了需要的可以直接在网上搜下下载如果是AS环境直接添加compile依赖就行了我这里是以Eclipse为例!直接放到项目中libs目录中然后buidpath—->add to path ok!本人电脑渣没办法!谅解哈!
首先看下dListBean代码很简单

`package com.zm.getareatest.bean;

public class DsListBean {
    private String ID;
    private String Areas;
    private String Status;

    public DsListBean(String iD, String areas, String status) {
        ID = iD;
        Areas = areas;
        Status = status;
    }

    public String getID() {
        return ID;
    }

    public String getAreas() {
        return Areas;
    }

    public String getStatus() {
        return Status;
    }

}
`

由于模拟网络加载数据这里我创建一个ProgressDialogUtils里面包括两个方法对话框的显示以及关闭代码如下

package com.zm.getareatest.util;

import android.app.ProgressDialog;
import android.content.Context;

public class ProgressDialogUtils {
    private static ProgressDialog mProgressDialog;

    /** * 显示ProgressDialog * @param context * @param message */
    public static void showProgressDialog(Context context, CharSequence message){
        if(mProgressDialog == null){
            mProgressDialog = ProgressDialog.show(context, "", message);
        }else{
            mProgressDialog.show();
        }
    }

    /** * 关闭ProgressDialog */
    public static void dismissProgressDialog(){
        if(mProgressDialog != null){
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
    }
}

下面就是访问WebService工具类我行封装网上也有很多类似代码

package com.zm.getareatest.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpResponseException;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.os.Handler;
import android.os.Message;

/** * 访问WebService的工具类, */
public class WebServiceUtils {
    // WebSerivce地址
    public static  String WEB_SERVICE_URL = "http://139.129.20.80:8088/WebSerive/CRMWebService.asmx";
    // 命名空间
    public static  String NAMESPACE = "http://tempuri.org/";
    // 含有3个线程的线程池
    private static final ExecutorService executorService = Executors
            .newFixedThreadPool(3);
    /** * * @param methodName * WebService的调用方法名 * @param properties * WebService的参数 * @param webServiceCallBack * 回调接口 */  
    public static  void CallWebService( final String methodName,
            HashMap<String, String> properties,
            final WebServiceCallBack webServiceCallBack) {      
        // 创建HttpTransportSE对象,传递WebService服务器地址
        final HttpTransportSE httpTransportSE = new HttpTransportSE(WEB_SERVICE_URL);       
        // 创建SoapObject对象
        SoapObject soapObject = new SoapObject(NAMESPACE, methodName);      
        // SoapObject添加参数
        if (properties != null) {
            for (Iterator<Map.Entry<String, String>> it = properties.entrySet()
                    .iterator(); it.hasNext();) {
                Map.Entry<String, String> entry = it.next();
                soapObject.addProperty(entry.getKey(), entry.getValue());
            }       
        }
         // 实例化SoapSerializationEnvelope,传入WebService的SOAP协议的版本号 
        final SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
          // 设置是否调用的是.Net开发的WebService 
        soapEnvelope.setOutputSoapObject(soapObject);
        soapEnvelope.dotNet =true;
        httpTransportSE.debug = true;

        // 用于子线程与主线程通信的Handler 
        final Handler mHandler = new Handler(){

            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                 // 将返回值回调到callBack的参数中 
                webServiceCallBack.CallBack((SoapObject) msg.obj);  
            }                       
        };

         // 开启线程去访问WebService 
        executorService.submit(new Runnable() {  

            @Override  
            public void run() {  
                SoapObject resultSoapObject = null;  
                try {  
                    httpTransportSE.call(NAMESPACE + methodName, soapEnvelope);  
                    if (soapEnvelope.getResponse() != null) {  
                        // 获取服务器响应返回的SoapObject 
                        resultSoapObject = (SoapObject) soapEnvelope.bodyIn;  
                    }  
                } catch (HttpResponseException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                } catch (XmlPullParserException e) {  
                    e.printStackTrace();  
                } finally {  
                    // 将获取的消息利用Handler发送到主线程 
                    mHandler.sendMessage(mHandler.obtainMessage(0,  
                            resultSoapObject));  
                }  
            }  
        });  
    }  
     /** * WebService的回调 * @author zhengmin * */
    public interface WebServiceCallBack {  
        public void CallBack(SoapObject result);  
    }      

}

然后就是将数据放在listview中进行绑定,开始我是将数据解析成json字符串初始化函数

private void init() {
        lv_area = (ListView) findViewById(R.id.province_list);

        // 显示进度条
        ProgressDialogUtils.showProgressDialog(this, "数据加载中...");
        WebServiceUtils.WEB_SERVICE_URL = this.WEB_SERVICE_URL;
        WebServiceUtils.NAMESPACE = this.NAMESPACE;
        // 通过工具类调用WebService接口
        WebServiceUtils.CallWebService(methodName, null,
                new WebServiceCallBack() {

                    // WebService接口返回的数据回调到这个方法中
                    @Override
                    public void CallBack(SoapObject result) {
                        // 关闭进度条
                        ProgressDialogUtils.dismissProgressDialog();
                        if (result != null) {
                            mAreaList = ParseSoapObject(result);
                            //lv_area.setAdapter(new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,mAreaList));
                            //getJson();
                            List<DsListBean> list = parseJson(mAreaList);

                        lv_area.setAdapter(new GetAreaAdapter(MainActivity.this, list));

                        } else {
                            Toast.makeText(MainActivity.this,
                                    "获取WebService数据出现错误", Toast.LENGTH_SHORT)
                                    .show();
                        }
                    }

                });

        // 点击事件
        lv_area.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {

            }
        });
    }

然后将xml解析成json字符串方法如下

/** * 解析SoapObject对象 - 区域数据 * * @param result * @return * @throws JSONException */
    private List<String> ParseSoapObject(SoapObject result) {
        String key = null;
        String jsonString = null;
        List<String> list = new ArrayList<String>();
        // Result
        SoapObject provinceSoapObject = (SoapObject) result
                .getProperty(methodName + "Result");
        if (provinceSoapObject == null) {
            return null;
        }
        for (int i = 0; i < provinceSoapObject.getPropertyCount(); i++) {
            list.add(provinceSoapObject.getProperty(i).toString());
            // getJson();
            Log.i("methodName:", methodName + "Result");


        }
        return list;
    }

最后在MainActvity中调用设置到listview中

lv_area.setAdapter(new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,mAreaList));

最后上MainActivity中全部代码

package com.zm.getareatest;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.ksoap2.serialization.SoapObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.zm.getareatest.adapter.GetAreaAdapter;
import com.zm.getareatest.bean.DsListBean;
import com.zm.getareatest.util.ProgressDialogUtils;
import com.zm.getareatest.util.WebServiceUtils;
import com.zm.getareatest.util.WebServiceUtils.WebServiceCallBack;


public class MainActivity extends Activity {
    // /GetArea
    private String WEB_SERVICE_URL = "http://139.129.20.80:8088/WebSerive/CRMWebService.asmx";
    // 命名空间";
    private String NAMESPACE = "http://tempuri.org/";
    private List<String> mAreaList = new ArrayList<String>(); // 区域列表
    private String methodName = "GetArea"; // 调用的方法名
    private ListView lv_area;
    private ArrayAdapter<String> adapter;
    private LayoutInflater mLayoutInflater;

    //
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    public void Dialog(){
         FlowDialog dialog=new FlowDialog(MainActivity.this);
         dialog.show();
    }

    private void init() {
        lv_area = (ListView) findViewById(R.id.province_list);

        // 显示进度条
        ProgressDialogUtils.showProgressDialog(this, "数据加载中...");
        WebServiceUtils.WEB_SERVICE_URL = this.WEB_SERVICE_URL;
        WebServiceUtils.NAMESPACE = this.NAMESPACE;
        // 通过工具类调用WebService接口
        WebServiceUtils.CallWebService(methodName, null,
                new WebServiceCallBack() {

                    // WebService接口返回的数据回调到这个方法中
                    @Override
                    public void CallBack(SoapObject result) {
                        // 关闭进度条
                        ProgressDialogUtils.dismissProgressDialog();
                        if (result != null) {
                            mAreaList = ParseSoapObject(result);
                            //lv_area.setAdapter(new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,mAreaList));

                        } else {
                            Toast.makeText(MainActivity.this,
                                    "获取WebService数据出现错误", Toast.LENGTH_SHORT)
                                    .show();
                        }
                    }

                });

        // 点击事件
        lv_area.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {

            }
        });
    }



    /** * 解析SoapObject对象 - 区域数据 * * @param result * @return * @throws JSONException */
    private List<String> ParseSoapObject(SoapObject result) {
        String key = null;
        String jsonString = null;
        List<String> list = new ArrayList<String>();
        // Result
        SoapObject provinceSoapObject = (SoapObject) result
                .getProperty(methodName + "Result");
        if (provinceSoapObject == null) {
            return null;
        }
        for (int i = 0; i < provinceSoapObject.getPropertyCount(); i++) {
            list.add(provinceSoapObject.getProperty(i).toString());
            // getJson();
            Log.i("methodName:", methodName + "Result");


        }
        return list;
    }


}

布局文件参考下其实您自己可以写我这里也贴出来了!

 xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button  android:id="@+id/btn_dialog_city" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="弹出对话框" android:onClick="Dialog"/> <ListView  android:id="@+id/province_list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:cacheColorHint="@android:color/transparent" android:fadingEdge="none" > </ListView> </LinearLayout> 

下面就是将适配器设置到listview中的效果,先看图片效果

其实跟上面不同的是上面的json字符串没有解析成jsonobject对象因此我们需要写个方法转下代码如下

private List<DsListBean> parseJson(List<String> mAreaList) {
        List<DsListBean> list = new ArrayList<DsListBean>();
        String json = mAreaList.get(0);
        try {
            JSONObject obj = new JSONObject(json);
            //获取dsList数组
            JSONArray arr = obj.getJSONArray("dsList");
            for (int i = 0; i < arr.length(); i++) {
                JSONObject obj2 = new JSONObject(arr.getJSONObject(i)
                        .toString());
                String id = obj2.getString("ID");
                String areas = obj2.getString("Areas");
                String status = obj2.getString("Status");
                list.add(new DsListBean(id, areas, status));
            }
            return list;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return list;
    }

然后在initview调用

private void init() {
        lv_area = (ListView) findViewById(R.id.province_list);

        // 显示进度条
        ProgressDialogUtils.showProgressDialog(this, "数据加载中...");
        WebServiceUtils.WEB_SERVICE_URL = this.WEB_SERVICE_URL;
        WebServiceUtils.NAMESPACE = this.NAMESPACE;
        // 通过工具类调用WebService接口
        WebServiceUtils.CallWebService(methodName, null,
                new WebServiceCallBack() {

                    // WebService接口返回的数据回调到这个方法中
                    @Override
                    public void CallBack(SoapObject result) {
                        // 关闭进度条
                        ProgressDialogUtils.dismissProgressDialog();
                        if (result != null) {
                            mAreaList = ParseSoapObject(result);
                            //返回数组列表
                            List<DsListBean> list = parseJson(mAreaList);
                           //将数据与adapter绑定
                        lv_area.setAdapter(new GetAreaAdapter(MainActivity.this, list));

                        } else {
                            Toast.makeText(MainActivity.this,
                                    "获取WebService数据出现错误", Toast.LENGTH_SHORT)
                                    .show();
                        }
                    }

                });

下面看下适配器代码,其实也很简单我这里直接上代码GetAreaAdapter

package com.zm.getareatest.adapter;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.zm.getareatest.R;

import com.zm.getareatest.bean.DsListBean;

public class GetAreaAdapter extends BaseAdapter {
    private Context mContext;
    private List<DsListBean> mList;
    private LayoutInflater mInflater;

    // 构造方法
    public GetAreaAdapter(Context mContext, List<DsListBean> mList) {

        this.mContext = mContext;
        this.mList = mList;
        mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.cityinfo, null);
            viewHolder.mTextView = (TextView) convertView.findViewById(R.id.tv_getarea);
            convertView.setTag(viewHolder);
        }
        else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        DsListBean dsListBean = mList.get(position);
        viewHolder.mTextView.setText(dsListBean.getID() + "\n" + dsListBean.getAreas() + "\n" + dsListBean.getStatus());

        return convertView;
    }

    class ViewHolder {
        private TextView mTextView;
    }
}

到这里基本结束了!

总结一下主要分为以下四点 1、解析xml数据 2、解析xml节点数据 3、解析json数据 4、将json字符串数据转成对象并与apapter绑定在一起 转载请注明出处!

网友评论