http://sizeed.blog.163.com/blog/static/9652545120111110105718361/
以如何根据一个手机号码获取号码归属地为例,详细地讲解一下WebService的调用
这里使用的WebService提供站是
http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?op=getMobileCodeInfo
我们用的是soap1.2协议,根据以上网页中的soap1.2实例来编写代码
SOAP 1.2
以下是 SOAP 1.2 请求和响应示例。所显示的占位符需替换为实际值。
POST /WebServices/MobileCodeWS.asmx HTTP/1.1
Host: webservice.webxml.com.cn
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?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>string</mobileCode>
<userID>string</userID>
</getMobileCodeInfo>
</soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?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>
<getMobileCodeInfoRespons e xmlns="http://WebXml.com.cn/">
<getMobileCodeInfoResult>string</getMobileCodeInfoResult>
</getMobileCodeInfoRespons e>
</soap12:Body>
</soap12:Envelope>
我们要发送的是一个post请求,完整的路径为
http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx
发送的数据为
<?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>string</mobileCode>
<userID>string</userID>
</getMobileCodeInfo>
</soap12:Body>
</soap12:Envelope>
为此我们要先写一个mobilesoap.xml文件,将第一个string改成手机号码(我们可以在xml文件中用占位符来表示),第二个string可以置空(表示免费用户)
将这些数据以http/post请求发送给服务器,服务器将返回一个响应,响应格式上面已经指出,通过解析响应的数据,就可以得到手机号码的归属地了
第一步,首先要读取我们自己定义的带有占位符的mobilesoap.xml文件
<?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>
以上是mobilesoap.xml文件中的内容
private static String readSoapFile(InputStream inStream, String mobile) throws Exception{
byte[] da ta = StreamTool.readInputStream(inStream);
String soapxml = new String(da ta);
Map<String, String> params = new HashMap<String, String>();
params.put("mobile", mobile);
return replace(soapxml, params);
}
public static String replace(String xml, Map<String, String> params)throws Exception{
String result = xml;
if(params!=null && !params.isEmpty()){
for(Map.Entry<String, String> entry : params.entrySet()){
String name = "\\$"+ entry.getKey();
Pattern pattern = Pattern.compile(name);
Matcher matcher = pattern.matcher(result);
if(matcher.find()){
result = matcher.replaceAll(entry.getValue());
}
}
}
return result;
}
以上代码就可以根据mobilesoap.xml输入流以及mobile参数构造出完整的基于soap的http请求中的数据部分,将这些数据加上请求头发送给服务器,服务器就可以返回我们所需要的归属地数据了
public static String getMobileAddress(InputStream inStream, String mobile)throws Exception{
String soap = readSoapFile(inStream, mobile);
byte[] da ta = soap.getBytes();
URL url = new URL("http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(5 * 1000);
conn.setDoOutput(true);//如果通过post提交数据,必须设置允许对外输出数据
conn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");
conn.setRequestProperty("Content-Length", String.valueOf(da ta.length));
OutputStream outStream = conn.getOutputStream();
outStream.write(da ta);
outStream.flush();
outStream.close();
if(conn.getResponseCode()==200){
return parseResponseXML(conn.getInputStream());
}
return null;
}
private static String parseResponseXML(InputStream inStream) throws Exception{
XmlPullParser parser = Xml.newPullParser();
parser.setInput(inStream, "UTF-8");
int eventType = parser.getEventType();//产生第一个事件
while(eventType!=XmlPullParser.END_DOCUMENT){//只要不是文档结束事件
switch (eventType) {
case XmlPullParser.START_TAG:
String name = parser.getName();//获取解析器当前指向的元素的名称
if("getMobileCodeInfoResult".equals(name)){
return parser.nextText();
}
break;
}
eventType = parser.next();
}
return null;
}
最后在我们的Activity就可以调用这些方法了,Activity简单界面如下
图 1
为此我们将这些方法定义在MobileAddressService类里面,然后就可以调用了
public class MainActivity extends Activity {
public static final String TAG = "MainActivity";
private EditText txt_mobile;
private Button btn_search;
private TextView lab_mobile;
public void on Create(Bundle savedInstanceState) {
super.on Create(savedInstanceState);
setContentView(R.layout.main);
txt_mobile = (EditText) findViewById(R.id.txt_mobile);
btn_search = (Button) findViewById(R.id.btn_search);
lab_mobile = (TextView) findViewById(R.id.mobile_address);
btn_search.setOnClickListener(new On ClickListener() {
public void on Click(View v) {
String mobileNum = txt_mobile.getText().toString();
InputStream inStream = getClass().getClassLoader().getResourceAsStream("mobilesoap.xml");
try {
String mobileAddress = MobileAddressService.getMobileAddress(inStream, mobileNum);
lab_mobile.setText(mobileAddress);
} catch (Exception e) {
Toast.makeText(MainActivity.this, "获取归属地失败!", 1);
Log.e(TAG,"获取归属地失败!");
}
}
});
}
}
至此,有关webservice调用阐述完毕!
另外一些代码:
Android中调用WebService的两种方法
第一种:使用KSOAP2库
原帖例子来自 http://www.cnblogs.com/ghj1976/archive/2011/04/26/2028904.html
这东西看起来好是好,可我最终还是以失败告终。
第一次崩溃是因为版本问题,主页上下载的最新2.5.7不知怎么搞的,编译没问题,一运行就程序崩溃。后来换成2.4的总算成功了。
第二次也不知道什么原因。例子能跑通,我自己的程序却死活不行,再次崩溃。
原帖分析的不错,copy一下。
1、指定 WebService 的命名空间和调用方法
import org.ksoap2.serialization.SoapObject; private static final String NAMESPACE = "http://WebXml.com.cn/"; private static final String METHOD_NAME = "getWeatherbyCityName"; SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME);
SoapObject类的第一个参数表示WebService的命名空间,可以从WSDL文档中找到WebService的命名空间。
第二个参数表示要调用的WebService方法名。
2、设置调用方法的参数值,如果没有参数,可以省略,设置方法的参数值的代码如下:
rpc.addProperty("theCityName", "北京");
要注意的是,addProperty方法的第1个参数虽然表示调用方法的参数名,但该参数值并不一定与服务端的WebService类中的方法参数名一致,只要设置参数的顺序一致即可。
3、生成调用Webservice方法的SOAP请求信息。
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.bodyOut = rpc; envelope.dotNet = true; envelope.setOutputSoapObject(rpc);
创建SoapSerializationEnvelope对象时需要通过SoapSerializationEnvelope类的构造方法设置SOAP协议的版本号。
该版本号需要根据服务端WebService的版本号设置。
在创建SoapSerializationEnvelope对象后,不要忘了设置SOAPSoapSerializationEnvelope类的bodyOut属性,
该属性的值就是在第一步创建的SoapObject对象。
4、创建HttpTransportsSE对象。
这里不要使用 AndroidHttpTransport ht = new AndroidHttpTransport(URL); 这是一个要过期的类
private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx"; HttpTransportSE ht = new HttpTransportSE(URL);
ht.debug = true;
5、使用call方法调用WebService方法
private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName"; ht.call(SOAP_ACTION, envelope);
网上有人说这里的call的第一个参数为null,但是经过我的测试,null是不行的。
第2个参数就是在第3步创建的SoapSerializationEnvelope对象。
6、获得WebService方法的返回结果
有两种方法:
1、使用getResponse方法获得返回数据。
private SoapObject detail; detail =(SoapObject) envelope.getResponse();
2、使用 bodyIn 及 getProperty。
private SoapObject detail; SoapObject result = (SoapObject)envelope.bodyIn; detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult");
7、 这时候执行会出错,提示没有权限访问网络
需要修改 AndroidManifest.xml 文件,赋予相应权限
简单来说就是增加下面这行配置:<uses-permission android:name="android.permission.INTERNET"></uses-permission>
第二种方法 直接写和读XML串
原帖来自 http://hi.baidu.com/lbp0408/blog/item/7971ae10d229b30c203f2e12.html/cmtid/d50a2ff4ca6692e07709d7e7
挺好用,就是往WebService发一段符合要求的XML字符串,再读返回的XML字符串。
不过XML的解析还得费点功夫
view plain copy to clipboard print ?
final String SERVER_URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx"; // 定义需要获取的内容来源地址
URL url = new URL(SERVER_URL);
URLConnection con = url.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Pragma:", "no-cache");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml");
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
String xmlInfo = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
+"<soap:Body>\n"
+"<getWeatherbyCityName xmlns=\"http://WebXml.com.cn/\">\n"
+"<theCityName>beijing</theCityName>\n"
+"</getWeatherbyCityName>\n"
+"</soap:Body>\n"
+"</soap:Envelope>\n";
Toast.makeText(this, xmlInfo, Toast.LENGTH_LONG).show();
发送
out.write(new String(xmlInfo.getBytes("UTF-8")));
out.flush();
out.close();
// 取返回值
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sBuilder = new StringBuilder();
String line = "";
for (line = br.readLine(); line != null; line = br.readLine()) {
sBuilder.append(line);
}