在 android 中调用 soap 网络服务
Call a soap webservice in android
我需要在 android 设备中调用 soap 网络服务。我已经在 Whosebug 和其他页面上阅读了很多文章,观看了视频...但是我已经尝试了一切,但我无法让它在我的 android 设备上运行,而且我无法在其中进行测试在模拟器上,因为我的电脑无法处理它们中的任何一个,所以我不知道错误是在代码上还是我的 android 设备的问题。
布局xml只有一个EditText、一个Button和一个TextView。
在此link中您可以看到我需要发送到网络服务的请求xml(我应该使用 SOAP 1.1 还是 SOAP 1.2?)
http://www.webservicex.net/globalweather.asmx?op=GetCitiesByCountry
这是我的实际代码,我尝试了很多其他方法,其中 none 对我有用。有什么帮助吗? (url、命名空间、soap_action 和 method_name 值没问题,不是吗?)
package com.example.doazdoas.webservice_prueba;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
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.widget.Toast;
import static android.content.ContentValues.TAG;
public class MainActivity extends Activity{
private TextView textResult;
private Button buttonSend;
String NAMESPACE = "http://www.webserviceX.NET/";
String METHOD_NAME = "GetCitiesByCountry";
String SOAP_ACTION = NAMESPACE + METHOD_NAME;
String URL = "http://www.webservicex.net/globalweather.asmx?WSDL";
private Object resultsRequestSOAP = null;
HttpTransportSE androidHttpTransport;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textResult = (TextView)findViewById(R.id.textResultado);
buttonSend = (Button)findViewById(R.id.buttonEnviar);
//setContentView(tv);
}
public void onClickEnviar(View view){
AsyncCallWS task = new AsyncCallWS();
task.execute();
}
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
@Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
sendRequest();
return null;
}
@Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
Log.d("dump Request: " ,androidHttpTransport.requestDump);
Log.d("dump response: " ,androidHttpTransport.responseDump);
}
}
public void sendRequest(){
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//SoapObject
request.addProperty("@CountryName", "SPAIN");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
androidHttpTransport = new HttpTransportSE(URL);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
resultsRequestSOAP = envelope.getResponse();
String[] results = (String[]) resultsRequestSOAP;
textResult.setText( results[0]);
}
catch (Exception aE)
{
aE.printStackTrace ();
}
}
}
您可以在doInBackGround
中进行任何UI相关操作,因此将它们移动到onPostExecute
方法中。
因为 doInBackGround
不是 UI 线程。请仔细阅读 AsyncTask 文档。无论您从 doInBackGround
返回的数据是什么,它都将作为 onPostExecute
.
的输入
所以按如下方式更改您的代码,
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
@Override
protected String[] doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
String[] data = sendRequest();
return data;
}
@Override
protected void onPostExecute(String[] result) {
Log.i(TAG, "onPostExecute");
if(result != null && result.length > 0){
textResult.setText( results[0]);
}
}
}
private String[] sendRequest(){
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//SoapObject
request.addProperty("@CountryName", "SPAIN");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
androidHttpTransport = new HttpTransportSE(URL);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
resultsRequestSOAP = envelope.getResponse();
String[] results = (String[]) resultsRequestSOAP;
}
catch (Exception aE)
{
aE.printStackTrace ();
}
}
您是否考虑过在不使用库的情况下发出 soap 请求?我之前遇到过同样的问题,它让我发现库会让你的工作变得更加困难,尤其是在对请求的结构进行更改时。这是在不使用库的情况下发出 soap 请求的方式:
首先,您需要知道如何使用 SOAP Ui,这是一个 windows 应用程序。您可以在此处导入您的 wsdl 文件,如果它的语法正确,您将看到一个屏幕,显示您的网络服务的请求正文。您可以输入测试值,您将获得一个响应结构。此 link 将指导您 ui 如何使用肥皂 ui https://www.soapui.org/soap-and-wsdl/working-with-wsdls.html
现在进入 android 代码:
我们将创建一个 class 名为 runTask 的扩展异步任务并使用 http 发送请求正文并获取请求响应:
private class runTask extends AsyncTask<String, String, String> {
private String response;
String string = "your string parameter"
String SOAP_ACTION = "your soap action here";
String stringUrl = "http://your_url_here";
//if you experience a problem with url remove the '?wsdl' ending
@Override
protected String doInBackground(String... params) {
try {
//paste your request structure here as the String body(copy it exactly as it is in soap ui)
//assuming that this is your request body
String body = "<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/">" +
"<soap:Body>"+
"<GetCitiesByCountryResponse xmlns="http://www.webserviceX.NET">"+
"<GetCitiesByCountryResult>"+string+"</GetCitiesByCountryResult>"+
"</GetCitiesByCountryResponse>"+
"</soap:Body>"+
"</soap:Envelope>";
try {
URL url = new URL(stringUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDefaultUseCaches(false);
conn.setRequestProperty("Accept", "text/xml");
conn.setRequestProperty("SOAPAction", SOAP_ACTION);
//push the request to the server address
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(body);
wr.flush();
//get the server response
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
response = builder.toString();//this is the response, parse it in onPostExecute
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
/**
* @see AsyncTask#onPostExecute(Object)
*/
@Override
protected void onPostExecute(String result) {
try {
Toast.makeText(this,"Response "+ result,Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
现在只需执行 class 并观看奇迹发生:
runTask runner = new runTask();
runner.execute();
您可以使用 DOM 或 SAX 解析器解析响应以获得所需的值。
随时要求进一步说明。
我需要在 android 设备中调用 soap 网络服务。我已经在 Whosebug 和其他页面上阅读了很多文章,观看了视频...但是我已经尝试了一切,但我无法让它在我的 android 设备上运行,而且我无法在其中进行测试在模拟器上,因为我的电脑无法处理它们中的任何一个,所以我不知道错误是在代码上还是我的 android 设备的问题。
布局xml只有一个EditText、一个Button和一个TextView。
在此link中您可以看到我需要发送到网络服务的请求xml(我应该使用 SOAP 1.1 还是 SOAP 1.2?) http://www.webservicex.net/globalweather.asmx?op=GetCitiesByCountry
这是我的实际代码,我尝试了很多其他方法,其中 none 对我有用。有什么帮助吗? (url、命名空间、soap_action 和 method_name 值没问题,不是吗?)
package com.example.doazdoas.webservice_prueba;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
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.widget.Toast;
import static android.content.ContentValues.TAG;
public class MainActivity extends Activity{
private TextView textResult;
private Button buttonSend;
String NAMESPACE = "http://www.webserviceX.NET/";
String METHOD_NAME = "GetCitiesByCountry";
String SOAP_ACTION = NAMESPACE + METHOD_NAME;
String URL = "http://www.webservicex.net/globalweather.asmx?WSDL";
private Object resultsRequestSOAP = null;
HttpTransportSE androidHttpTransport;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textResult = (TextView)findViewById(R.id.textResultado);
buttonSend = (Button)findViewById(R.id.buttonEnviar);
//setContentView(tv);
}
public void onClickEnviar(View view){
AsyncCallWS task = new AsyncCallWS();
task.execute();
}
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
@Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
sendRequest();
return null;
}
@Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
Log.d("dump Request: " ,androidHttpTransport.requestDump);
Log.d("dump response: " ,androidHttpTransport.responseDump);
}
}
public void sendRequest(){
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//SoapObject
request.addProperty("@CountryName", "SPAIN");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
androidHttpTransport = new HttpTransportSE(URL);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
resultsRequestSOAP = envelope.getResponse();
String[] results = (String[]) resultsRequestSOAP;
textResult.setText( results[0]);
}
catch (Exception aE)
{
aE.printStackTrace ();
}
}
}
您可以在doInBackGround
中进行任何UI相关操作,因此将它们移动到onPostExecute
方法中。
因为 doInBackGround
不是 UI 线程。请仔细阅读 AsyncTask 文档。无论您从 doInBackGround
返回的数据是什么,它都将作为 onPostExecute
.
所以按如下方式更改您的代码,
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
@Override
protected String[] doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
String[] data = sendRequest();
return data;
}
@Override
protected void onPostExecute(String[] result) {
Log.i(TAG, "onPostExecute");
if(result != null && result.length > 0){
textResult.setText( results[0]);
}
}
}
private String[] sendRequest(){
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//SoapObject
request.addProperty("@CountryName", "SPAIN");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
androidHttpTransport = new HttpTransportSE(URL);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
resultsRequestSOAP = envelope.getResponse();
String[] results = (String[]) resultsRequestSOAP;
}
catch (Exception aE)
{
aE.printStackTrace ();
}
}
您是否考虑过在不使用库的情况下发出 soap 请求?我之前遇到过同样的问题,它让我发现库会让你的工作变得更加困难,尤其是在对请求的结构进行更改时。这是在不使用库的情况下发出 soap 请求的方式: 首先,您需要知道如何使用 SOAP Ui,这是一个 windows 应用程序。您可以在此处导入您的 wsdl 文件,如果它的语法正确,您将看到一个屏幕,显示您的网络服务的请求正文。您可以输入测试值,您将获得一个响应结构。此 link 将指导您 ui 如何使用肥皂 ui https://www.soapui.org/soap-and-wsdl/working-with-wsdls.html
现在进入 android 代码:
我们将创建一个 class 名为 runTask 的扩展异步任务并使用 http 发送请求正文并获取请求响应:
private class runTask extends AsyncTask<String, String, String> {
private String response;
String string = "your string parameter"
String SOAP_ACTION = "your soap action here";
String stringUrl = "http://your_url_here";
//if you experience a problem with url remove the '?wsdl' ending
@Override
protected String doInBackground(String... params) {
try {
//paste your request structure here as the String body(copy it exactly as it is in soap ui)
//assuming that this is your request body
String body = "<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/">" +
"<soap:Body>"+
"<GetCitiesByCountryResponse xmlns="http://www.webserviceX.NET">"+
"<GetCitiesByCountryResult>"+string+"</GetCitiesByCountryResult>"+
"</GetCitiesByCountryResponse>"+
"</soap:Body>"+
"</soap:Envelope>";
try {
URL url = new URL(stringUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDefaultUseCaches(false);
conn.setRequestProperty("Accept", "text/xml");
conn.setRequestProperty("SOAPAction", SOAP_ACTION);
//push the request to the server address
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(body);
wr.flush();
//get the server response
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
response = builder.toString();//this is the response, parse it in onPostExecute
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
/**
* @see AsyncTask#onPostExecute(Object)
*/
@Override
protected void onPostExecute(String result) {
try {
Toast.makeText(this,"Response "+ result,Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
现在只需执行 class 并观看奇迹发生:
runTask runner = new runTask();
runner.execute();
您可以使用 DOM 或 SAX 解析器解析响应以获得所需的值。 随时要求进一步说明。