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

来源:互联网 发布:java开源论坛 编辑:程序博客网 时间:2024/06/11 05:07

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>
    <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/">
      <getMobileCodeInfoResult>string</getMobileCodeInfoResult>
    </getMobileCodeInfoResponse>
  </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[] data = StreamTool.readInputStream(inStream);
String soapxml = new String(data);
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[] data = 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(data.length));
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
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简单界面如下
Android开发之如何调用WebService
图 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 onCreate(Bundle savedInstanceState) {
        super.onCreate(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 OnClickListener() {
public void onClick(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 plaincopy to clipboardprint?
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);  
}
原创粉丝点击