Android--通过Http协议向web服务器发送XML数据和调用webService

笔记摘要:

    这里介绍了向web服务器提交XML实体数据,通过将请求参数和请求方法按照某种协议封装在XML文件中,提交到WebServices(网络上提供的API,天气查询,股票行情

    等服务),webServices通过调用相应的方法,返回某种协议的结果,最终通过客户端对该种协议的数据进行解析,最终将结果显示给用户。这里通过号码归属地查询来演

    示该提交方式的用处。


效果图



一、开发前奏

WebServices:看作是发布在网络上的API


思路:

    客户端通过xml文件将需要调用的方法和参数封装发送给webServicewebSerevice根据信息通过反射调用相应的方法,然后将结果封装成xml文件返回给客户端,

  客户端对返回的数据进行解析,最终显示在用户应用的界面


注意:以实体方式发送数据,必须使用POST方式提交,


二、步骤


1、创建一个web服务器,用于提供web服务

2、创建一个业务类,用于处理提交的数据

3、调用手机归属地查询服务的API

   登陆http://webservice.webxml.com.cn,进入到手机归属地查询API的页面,可以看到,该API有指定协议soap的数据格式,所以我们要发送相应的soap协议

   的数据,所以创建一个soap协议的xml文件soap12.xml用于提交数据

4、对webService返回的数据进行解析

5、设计Android应用页面,输入电话号码,调用业务类返回号码归属地,显示在应用页面



三、代码体现


出现的错误:

请求类型书写的错误,文件名的错误。

在替换占位符时,replace的使用错误,导致每次的结果为:输入的号码错误。应该使用replaceAll方法,


号码归属地API请求方式:soap协议的数据

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <getMobileCodeInfo xmlns="http://WebXml.com.cn/">
      <mobileCode>$mobile</mobileCode>
      <userID></userID>
    </getMobileCodeInfo>
  </soap12:Body>
</soap12:Envelope>


号码归属地soap协议返回的数据格式

//webService返回数据格式
<?xml version="1.0" encoding="utf-8"?>
	<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
	  <soap12:Body>
	    <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/">
	      <getMobileCodeInfoResult>string</getMobileCodeInfoResult>
	    </getMobileCodeInfoResponse>
	  </soap12:Body>
	</soap12:Envelope>
	 * */




AndroidMainfest.xml文件

<!-- 访问Internet权限 -->  
   <uses-permission android:name="android.permission.INTERNET"/>  


string.xml

<resources>

    <string name="app_name">MobileAddressQuery</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_mobile_address_query">MobileAddressQuery</string>
	<string name="mobile">手机号</string>
	<string name="button">归属地查询</string>
	<string name="error">手机归属地查询失败</string>
</resources>


布局文件

<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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        tools:context=".MobileAddressQuery" />
	
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/mobile"
        android:id="@+id/mobileView"
        />
     <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/mobileText"
        android:layout_below="@+id/mobileView"
        />
    	
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:text="@string/button"
        android:onClick="query"
        android:layout_below="@+id/mobileText"
        />
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/address"
        android:layout_below="@+id/button"
        />
</RelativeLayout>



号码归属地查询业务类


说明:

    读取自定义的soap协议的xml文件,发送请求道webService,获取webService返回的数据,并对于webService返回的数据进行解析

package cn.xushuai.service;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;

import cn.xushuai.util.StreamTool;

/*
 * 获取手机号归属地
 * 
 * */
public class AddressService {
	public static String getAddress(String mobile) throws Exception{
		//读取soap协议的数据,将请求参数和方法传送给webService
		String soap = readSoap();
		soap = soap.replaceAll("\\$mobile", mobile);//将用户输入的电话号码替换掉原来的占位符
		byte[] entity = soap.getBytes();
		
		String path="http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";//请求路径
		HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
		conn.setConnectTimeout(5000);
		conn.setRequestMethod("POST");
		conn.setDoOutput(true);
		conn.setRequestProperty("Content-Type", "application/soap+xml;charset=UTF-8");//请求类型为soap+xml
		conn.setRequestProperty("Content-Length", String.valueOf(entity.length));
		conn.getOutputStream().write(entity);//将实体参数写入到内存中,并没有发送给webService
		if(conn.getResponseCode()==200){	//判断返回码的同时将请求传送到webService
			//对返回结果进行解析
			return parseSOAP(conn.getInputStream());
		}
		return null;
	}

	
	
	//通过pull解析方式对webService返回的数据进行解析
	private static String parseSOAP(InputStream xml) throws XmlPullParserException, IOException {

		XmlPullParser pullParser = Xml.newPullParser();//获取pull解析器
		pullParser.setInput(xml,"UTF-8");//设置输出流和编码格式
		int event = pullParser.getEventType();//获取触发事件类型
		while(event != pullParser.END_TAG){
			switch(event){
			case XmlPullParser.START_TAG://触发开始节点事件
			if("getMobileCodeInfoResult".equals(pullParser.getName())){//对获取的节点名称进行比较
				return pullParser.nextText(); //返回该及点的内容
				}
			break;
			}
			event = pullParser.next();//进行下一次遍历
		}
		return null;
	}
	/*
	 * 读取soap协议的请求数据
	 * */
	private static String readSoap() throws Exception {
		InputStream inStream = AddressService.class.getClassLoader().getResourceAsStream("soap12.xml");//通过类加载器加载本地本件
		byte[] data = StreamTool.read(inStream);
		return new String(data);//将读取的字节数据转换成字符数据返回
	}
}


用于读取数据的工具类

package cn.xushuai.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/*
	读取流中的数据
	@return
 * */
public class StreamTool {
	public static byte[] read(InputStream inStream) throws Exception{
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();//创建一个内存输出流,存放数据
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = inStream.read(buf))!=-1){	//不断读取
			outStream.write(buf,0,len);
		}
		inStream.close();
		return outStream.toByteArray();//返回内存中的数据
	}
}

AndroidMainfest.xml文件

添加网络许可

<!-- 访问Internet权限 -->  
   <uses-permission android:name="android.permission.INTERNET"/>  


string.xml

<resources>

    <string name="app_name">MobileAddressQuery</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_mobile_address_query">MobileAddressQuery</string>
	<string name="mobile">手机号</string>
	<string name="button">归属地查询</string>
	<string name="error">手机归属地查询失败</string>
</resources>


布局文件

<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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        tools:context=".MobileAddressQuery" />
	
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/mobile"
        android:id="@+id/mobileView"
        />
     <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/mobileText"
        android:layout_below="@+id/mobileView"
        />
    	
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:text="@string/button"
        android:onClick="query"
        android:layout_below="@+id/mobileText"
        />
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/address"
        android:layout_below="@+id/button"
        />
</RelativeLayout>

posted @ 2013-01-21 16:17  积小流,成江海  阅读(500)  评论(0编辑  收藏  举报