【Android应用开发技术:网络通信】Android下的SOAP处理

原创 2015年09月29日 14:11:13

作者:郭孝星
微博:郭孝星的新浪微博
邮箱:guoxiaoxingv@163.com
博客:http://blog.csdn.net/allenwells
Github:https://github.com/guoxiaoxing

一 SOAP基础

简单对象访问协议(Simple Object Access Protocol,SOAP)是一种标准化的通信规范,主要用于 Web 服务(Web service)。SOAP 的出现可以使网页服务器(Web Server)从XML 数据库中提取数据时,无需花时间去格式化页面,并能够让不同应用程序之间通过HTTP 协议,以 XML 格式互相交换彼此的数据,使这个交换过程与编程语言、平台和硬件无关。

SOAP主要有以下优点:

  • SOAP 是可扩展的。SOAP 无需中断已有的应用程序,SOAP 客户端、服务器和协议自身都能发展。而且 SOAP 能极好地支持中间介质和层次化的体系结构。
  • SOAP 是简单的。客户端发送一个请求,调用相应的对象,然后服务器返回结果。这些消息是 XML 格式的,并且封装成符合 HTTP 协议的消息。因此,它符合任何路由器、防火墙或代理服务器的要求。
  • SOAP 是完全和厂商无关的。SOAP 可以相对于平台、操作系统、目标模型和编程语言独立实现。另外,传输和语言绑定以及数据编码的参数选择都是由具体的实现决定的。
  • SOAP与编程语言无关。SOAP 可以使用任何语言来完成, 只要客户端发送正SOAP 请求(也就是说,传递一个合适的参数给一个实际的远端服务器)。SOAP 没有对象模型,应用程序可以捆绑在任何对象模型中。

1.1 SOAP消息

SOAP 使用 Internet 应用层协议作为其传输协议。SMTP 以及 HTTP 协议都可以用来传输 SOAP 消息,SOAP 亦可以通过 HTTPS 传输。一条 SOAP 消息就是一个普通的 XML 文档。

1.1.1 SOAP消息格式

SOAP消息包含以下元素:

  • 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息。
  • 可选的 Header 元素,包含头部信息。
  • 必需的 Body 元素,包含所有的调用和响应信息。
  • 可选的 Fault 元素,提供有关在处理此消息时发生错误的信息。

这里写图片描述

举例

请求时发送的消息如下所示:

<soapenv:Envelope
xmlns:soapenv="http:// schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http:// www.w3.org/2001/XMLSchema"
xmlns:xsi="http:// www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<req:echo xmlns:req="http:// localhost:8080/axis2/services/MySer-vice/">
<req:category>classifieds</req:category>
</req:echo>
</soapenv:Body>
</soapenv:Envelope>

响应时发送的消息如下所示:

<soapenv:Envelope
xmlns:soapenv="http:// schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http:// schemas.xmlsoap.org/ws/2004/08/addressing">
<soapenv:Header>
<wsa:ReplyTo><wsa:Address>http:// schemas.xmlsoap.org/ws/2004/08/
addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:From><wsa:Address>http:// localhost:8080/axis2/
services/MyService</wsa:Address>
</wsa:From>
<wsa:MessageID>ECE5B3F187F29D28BC11433905662036</wsa:MessageID>
</soapenv:Header>
<soapenv:Body>
<req:echo xmlns:req="http:// localhost:8080/axis2/services/MyService/">
<req:category>classifieds</req:category>
</req:echo>
</soapenv:Body>
</soapenv:Envelope>

1.1.2 SOAP消息语法

SOAP 消息的重要的语法规则如下:

  • SOAP 消息必须使用 XML 来编码。
  • SOAP 消息必须使用 SOAP Envelope 命名空间。
  • SOAP 消息不能包含 DTD 引用。
  • SOAP 消息不能包含 XML 处理指令。

二 SOAP处理

WebService是一种基于SOAP协议的远程调用标准, 通过WebService 可以将不同操作系统平台、不同语言、不同技术整合到一块。

1 添 加 ksoap2 包。在 Android SDK中并没有提供调用 WebService 的库,因此,需要使用第三方的 SDK 来调用 WebService。比较常用的是Ksoap2,将JAR包放入工程中。

2 指定 WebService 的命名空间和调用的方法名,如:

SoapObject request =new SoapObject(http:// service,"getName");

SoapObject 类的第一个参数表示 WebService 的命名空间,可以从 WSDL 文档中找到
WebService 的命名空间;第二个参数表示要调用的 WebService 方法名。

3 设置调用方法的参数值,如果没有参数,可以省略。设置方法的参数值的代码如下所示:

Request.addProperty("param1","value");
Request.addProperty("param2","value");

要注意的是,addProperty 方法的第 1 个参数虽然表示调用方法的参数名,但该参数值
并不一定与服务端的 WebService 类中的方法参数名一致,只要设置参数的顺序一致即可。

4 生成调用 WebService 方法的 SOAP 请求信息。该信息由 SoapSerializationEnvelope
对象描述,代码如下所示:

SoapSerializationEnvelope envelope=
new SoapSerializationEnvelope(SoapEnvelope.VER11);
Envelope.bodyOut = request;

创建 SoapSerializationEnvelope 对象时需要通过 SoapSerializationEnvelope 类的构造方
法设置 SOAP 协议的版本号。该版本号需要根据服务端 WebService 的版本号设置。在创建 SoapSerializationEnvelope 对 象 后, 不 要 忘 了 设 置 SOAPSoapSerializationEnvelope 类 的bodyOut 属性,该属性的值就是在步骤 2 创建的 SoapObject 对象。

5 创 建 HttpTransportsSE 对 象。 通 过 HttpTransportsSE 类 的 构 造 方 法 可 以 指 定
WebService 的 WSDL 文档的 URL。

HttpTransportSE ht=new HttpTransportSE
("http:// fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl");

6 使用 call 方法调用 WebService 方法,代码如下:

ht.call(null,envelope);

call 方法的第一个参数一般为 null,第 2 个参数就是在步骤 4 创建的 SoapSerialization-
Envelope 对象。

7 使用 getResponse 方法获得 WebService 方法的返回结果,代码如下:

SoapObject soapObject =(SoapObject)envelope.getResponse();

8 解析返回的内容。

举例

SOAP解析天气服务:从客户端获取用户输入的城市名称,将城市名称打包成符SOAP 协议的查询消息,把查询信息发送给提供 SOAP 天气服务的服务器 ;服务器内部进行操作之后,返回给客户端查询城市的天气信息,该信息以 SOAP 格式返回,客户端对其进行解析之后显示给用户。

布局文件代码

<RelativeLayout xmlns:android="http:// schemas.android.com/apk/res/android"
xmlns:tools="http:// schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- 显示控件 , 用于显示天气情况 -->
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="@dimen/padding_medium"
tools:context=".AndroidSoapActivity" />
<!-- 按钮 , 用户提交城市名称时候单击该按钮 -->
<Button
android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/textView1"
android:text="@string/search" />
<!-- 输入控件 , 用户输入城市名称 -->
<EditText
android:id="@+id/cityName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="@string/cityName" />
</RelativeLayout>

业务逻辑代码

import java.io.UnsupportedEncodingException;
// 加入需要使用的 ksoap2 包中的类
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
// SOAP 方式查询天气情况
public class AndroidSoapActivity extends Activity {
// 指定命名空间
private static final String NAMESPACE = "http:// WebXml.com.cn/";
// 给出接口地址
private static String URL =
"http:// www.webxml.com.cn/webservices/weatherwebservice.asmx";
// 设置方法名
private static final String METHOD_NAME = "getWeatherbyCityName";
// 设置查询接口参数
private static String SOAP_ACTION =
"http:// WebXml.com.cn/getWeatherbyC-ityName";
// 定义字符串,保存天气信息
private String weatherToday;
// 定义按钮
private Button okButton;
// 定义 SoapObject 对象
private SoapObject detail;
// 定义输入控件
private EditText cityNameText;
// 定义显示控件,显示天气信息
private TextView cityMsgView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 加载布局文件
setContentView(R.layout.activity_android_soap);
// 获取控件
cityNameText =(EditText)findViewById(R.id.cityName);
cityMsgView = (TextView)findViewById(R.id.textView1);
okButton = (Button) findViewById(R.id.ok);
// 为按钮添加事件监听
okButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
// 执行获取天气信息的操作
new showWeatherAsyncTask().execute();
}
});
}
// 使用 AsyncTask 异步方式获取并显示天气信息
private class showWeatherAsyncTask extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... Urls) {
// 获取并显示天气信息
showWeather();
return null;
}
protected void onPostExecute(String result) {
}
 77
};
// 获取并显示天气信息
private void showWeather() {
// 获取需要查询的城市名称
String city = cityNameText.getText().toString().trim();
// 检测城市名称是否为空
if(!city.isEmpty()){
// 获取指定城市的天气信息
getWeather(city);
}
}
// 获取指定城市的天气信息,参数 cityName 为指定的城市名称
public void getWeather(String cityName) {
try {
// 新建 SoapObject 对象
SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME);
// 给 SoapObject 对象添加属性
rpc.addProperty("theCityName", cityName);
// 创建 HttpTransportSE 对象,并指定 WebService 的 WSDL 文档的 URL
HttpTransportSE ht = new HttpTransportSE(URL);
// 设置 debug 模式
ht.debug = true;
// 获得序列化的 envelope
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
// 设置 bodyOut 属性的值为 SoapObject 对象 rpc
envelope.bodyOut = rpc;
// 指定 webservice 的类型为 dotNet
envelope.dotNet = true;
envelope.setOutputSoapObject(rpc);
// 使用 call 方法调用 WebService 方法
ht.call(SOAP_ACTION, envelope);
// 获取返回结果
SoapObject result = (SoapObject) envelope.bodyIn;
// 使用 getResponse 方法获得 WebService 方法的返回结果
detail = (SoapObject)result.getProperty("getWeatherbyCityNameResult");
System.out.println("detail" + detail);
// 解析返回的数据信息为 SoapObject 对象,对其进行解析
parseWeather(detail);
return;
} catch (Exception e) {
e.printStackTrace();
}
}
// 解析 SoapObject 对象
private void parseWeather(SoapObject detail)throws UnsupportedEncodingException {
// 获取日期
String date = detail.getProperty(6).toString();
// 获取天气信息
weatherToday = " 今天:" + date.split(" ")[0];
weatherToday = weatherToday + " 天气:" + date.split(" ")[1];
weatherToday = weatherToday + " 气温:" + detail.getProperty(5).toString() ;
weatherToday = weatherToday + " 风力: " + detail.getProperty(7).toString()+ " ";
System.out.println("weatherToday is " + weatherToday);
// 显示到 cityMsgView 控件上
cityMsgView.setText(weatherToday);
}
// 创建 Menu 菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_android_soap, menu);
return true;
}
}

Android进价篇-SOAP协议

使用SOAP协议的前提是你必须下载一个KSOAP包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包 然后操作的第一步: 实例化So...
  • a603473186
  • a603473186
  • 2012年03月09日 16:59
  • 11484

Java 调用Web service 添加认证头(soapenv:Header)

有时候调用web service 会出现 Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]...
  • oscar999
  • oscar999
  • 2014年10月22日 08:34
  • 35678

Retrofit框架请求SOAP WebService

使用Retrofit框架进行SOAP Webservice请求,包含SOAP版本区分
  • smileiam
  • smileiam
  • 2016年07月19日 18:03
  • 6552

Android WebService(基于SOAP协议)

package com.nenglong.wsclient; import java.io.IOException; import org.ksoap2.SoapEnvelope; import ...
  • long704480904
  • long704480904
  • 2013年03月05日 14:41
  • 29541

Android 利用soap协议与服务端进行通信

首先要使用soap与服务器通信,需要下载KSOAP包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包(或者版本更高的)。      接...
  • vaecer
  • vaecer
  • 2015年08月24日 01:15
  • 1737

Android程序使用SOAP调用远程WebService服务

在如今的应用程序中,不可能不使用到网络,并且后台一定是有服务器作为支撑的。如今最常见的调用方式有HTTP的GET ,POST方式,返回JSON或者XML数据。但是也有一种常见的形式就是调用WebSer...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2015年08月06日 16:50
  • 3342

Android 直接写和读XML串方式 调用 WebService soap

http://sizeed.blog.163.com/blog/static/9652545120111110105718361/ 以如何根据一个手机号码获取号码归属地为例,详细地讲解一下W...
  • forlong401
  • forlong401
  • 2012年07月07日 22:24
  • 3432

android上使用Soap协议的简单实例

话不多说,先上代码: package XXX; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject...
  • androidzhaoxiaogang
  • androidzhaoxiaogang
  • 2012年11月18日 14:09
  • 9586

Android与服务器端数据交互(基于SOAP协议整合android+webservice)

  • 2013年12月15日 12:40
  • 484KB
  • 下载

android soap协议与webservice

今天偶然听说到soap协议的数据传输,没事就来看看,简单上网搜了下,总结如下: 首先,soap与http、socket都是一种数据传输协议,并不是说webservice一定要用soap协议,只不过w...
  • explorerqp
  • explorerqp
  • 2015年05月30日 00:02
  • 1193
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Android应用开发技术:网络通信】Android下的SOAP处理
举报原因:
原因补充:

(最多只允许输入30个字)