我正在用计算器的Java开发SOAP应用程序,我想从正在开发的Android应用程序中使用它,问题是它会产生以下错误:
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.calculadora, PID: 23487
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.RuntimeException: Cannot serialize: 2.5
at org.ksoap2.serialization.SoapSerializationEnvelope.writeElement(SoapSerializationEnvelope.java:629)
at org.ksoap2.serialization.SoapSerializationEnvelope.writeProperty(SoapSerializationEnvelope.java:613)
at org.ksoap2.serialization.SoapSerializationEnvelope.writeObjectBody(SoapSerializationEnvelope.java:582)
at org.ksoap2.serialization.SoapSerializationEnvelope.writeObjectBody(SoapSerializationEnvelope.java:566)
at org.ksoap2.serialization.SoapSerializationEnvelope.writeElement(SoapSerializationEnvelope.java:623)
at org.ksoap2.serialization.SoapSerializationEnvelope.writeBody(SoapSerializationEnvelope.java:547)
at org.ksoap2.SoapEnvelope.write(SoapEnvelope.java:192)
at org.ksoap2.transport.Transport.createRequestData(Transport.java:74)
at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:58)
at com.example.calculadora.CallAsynchronousWS.callActionWS(CallAsynchronousWS.java:63)
at com.example.calculadora.CallAsynchronousWS.doInBackground(CallAsynchronousWS.java:34)
at com.example.calculadora.CallAsynchronousWS.doInBackground(CallAsynchronousWS.java:17)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
基本上,我正在做的是通过按应用程序按钮,实例化InitialOperarListener
类,这将调用在SOAP应用程序和Android应用程序之间实现连接的类。
MainActivity
代码如下:
public class MainActivity extends AppCompatActivity {
private EditText numero1;
private EditText numero2;
private TextView resultado;
private Button operar;
private Spinner operaciones;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
numero1 = (EditText) this.findViewById(R.id.textBox);
numero2 = (EditText) this.findViewById(R.id.textBox2);
resultado = (TextView) this.findViewById(R.id.textViewResultado);
operar = (Button) this.findViewById(R.id.button);
operaciones = (Spinner) this.findViewById(R.id.spinner);
String[] op = {"Sumar", "Restar", "Multiplicar", "Dividir", "Potencia", "Raiz", "Seno", "Coseno"};
operaciones.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, op));
operar.setOnClickListener(new InitialOperarListener(this));
}
public static boolean isOnline(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
}
/**
* @return the numero1
*/
public EditText getNumero1() {
return numero1;
}
/**
* @param numero1 the numero1 to set
*/
public void setNumero1(EditText numero1) {
this.numero1 = numero1;
}
/**
* @return the numero2
*/
public EditText getNumero2() {
return numero2;
}
/**
* @param numero2 the numero2 to set
*/
public void setNumero2(EditText numero2) {
this.numero2 = numero2;
}
/**
* @return the resultado
*/
public TextView getResultado() {
return resultado;
}
/**
* @param resultado the resultado to set
*/
public void setResultado(TextView resultado) {
this.resultado = resultado;
}
}
这是事件的侦听器。
public class InitialOperarListener implements OnClickListener {
private MainActivity activity;
public InitialOperarListener(MainActivity activity) {
this.activity = activity;
}
@Override
public void onClick(View v) {
CallAsynchronousWS tarea = new CallAsynchronousWS(activity);
tarea.execute();
}
}
这是SOAP连接,使用android的ksoap2库,我要做的是除了操作所需的其他参数之外,还定义了参数:
public class CallAsynchronousWS extends AsyncTask<Double, Void, Void> {
private static final String NAMESPACE = "http://servicios/";
private static String URL = "http://192.168.0.19:8080/WebServer/Calculadora?WSDL";
private static final String METHOD_NAME = "sumar";
private static final String SOAP_ACTION = "http://servicios/sumar";
private MainActivity activity;
private Double response;
public CallAsynchronousWS(MainActivity activity) {
this.activity = activity;
}
@Override
protected Void doInBackground(Double... params) {
callActionWS();
return null;
}
@Override
protected void onPostExecute(Void result) {
activity.getResultado().setText(response.toString());
}
@Override
protected void onPreExecute() {
activity.getResultado().setText("Calculating...");
}
@Override
protected void onProgressUpdate(Void... values) {
}
void callActionWS() {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("i", Double.parseDouble(activity.getNumero1().getText().toString()));
request.addProperty("j", Double.parseDouble(activity.getNumero2().getText().toString()));
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = false;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response;
response = (SoapPrimitive) envelope.getResponse();
this.response = Double.parseDouble(response.toString());
} catch (SoapFault e) {
Utilities.messageBox(activity, e.getMessage());
activity.getResultado().setText("Error: " + e.getMessage());
} catch (IOException e) {
Utilities.messageBox(activity, e.getMessage());
activity.getResultado().setText("Error: " + e.getMessage());
} catch (XmlPullParserException e) {
Utilities.messageBox(activity, e.getMessage());
activity.getResultado().setText("Error: " + e.getMessage());
}
}
}
更新:另外,我添加了soap应用程序的WDSL文件,以可视化我在应用程序内部具有的参数。
<!--
Published by JAX-WS RI (http://jax-ws.java.net). RI's version is Metro/2.3.2-b608 (trunk-7979; 2015-01-21T12:50:19+0000) JAXWS-RI/2.2.11-b150120.1832 JAXWS-API/2.2.12 JAXB-RI/2.2.12-b141219.1637 JAXB-API/2.2.13-b141020.1521 svn-revision#unknown.
-->
<!--
Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is Metro/2.3.2-b608 (trunk-7979; 2015-01-21T12:50:19+0000) JAXWS-RI/2.2.11-b150120.1832 JAXWS-API/2.2.12 JAXB-RI/2.2.12-b141219.1637 JAXB-API/2.2.13-b141020.1521 svn-revision#unknown.
-->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://servicios/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://servicios/" name="Calculadora">
<types>
<xsd:schema>
<xsd:import namespace="http://servicios/" schemaLocation="http://192.168.0.19:8080/WebServer/Calculadora?xsd=1"/>
</xsd:schema>
</types>
<message name="multiplicar">
<part name="parameters" element="tns:multiplicar"/>
</message>
<message name="multiplicarResponse">
<part name="parameters" element="tns:multiplicarResponse"/>
</message>
<message name="dividir">
<part name="parameters" element="tns:dividir"/>
</message>
<message name="dividirResponse">
<part name="parameters" element="tns:dividirResponse"/>
</message>
<message name="restar">
<part name="parameters" element="tns:restar"/>
</message>
<message name="restarResponse">
<part name="parameters" element="tns:restarResponse"/>
</message>
<message name="sumar">
<part name="parameters" element="tns:sumar"/>
</message>
<message name="sumarResponse">
<part name="parameters" element="tns:sumarResponse"/>
</message>
<message name="hello">
<part name="parameters" element="tns:hello"/>
</message>
<message name="helloResponse">
<part name="parameters" element="tns:helloResponse"/>
</message>
<message name="modulo">
<part name="parameters" element="tns:modulo"/>
</message>
<message name="moduloResponse">
<part name="parameters" element="tns:moduloResponse"/>
</message>
<portType name="Calculadora">
<operation name="multiplicar">
<input wsam:Action="http://servicios/Calculadora/multiplicarRequest" message="tns:multiplicar"/>
<output wsam:Action="http://servicios/Calculadora/multiplicarResponse" message="tns:multiplicarResponse"/>
</operation>
<operation name="dividir">
<input wsam:Action="http://servicios/Calculadora/dividirRequest" message="tns:dividir"/>
<output wsam:Action="http://servicios/Calculadora/dividirResponse" message="tns:dividirResponse"/>
</operation>
<operation name="restar">
<input wsam:Action="http://servicios/Calculadora/restarRequest" message="tns:restar"/>
<output wsam:Action="http://servicios/Calculadora/restarResponse" message="tns:restarResponse"/>
</operation>
<operation name="sumar">
<input wsam:Action="http://servicios/Calculadora/sumarRequest" message="tns:sumar"/>
<output wsam:Action="http://servicios/Calculadora/sumarResponse" message="tns:sumarResponse"/>
</operation>
<operation name="hello">
<input wsam:Action="http://servicios/Calculadora/helloRequest" message="tns:hello"/>
<output wsam:Action="http://servicios/Calculadora/helloResponse" message="tns:helloResponse"/>
</operation>
<operation name="modulo">
<input wsam:Action="http://servicios/Calculadora/moduloRequest" message="tns:modulo"/>
<output wsam:Action="http://servicios/Calculadora/moduloResponse" message="tns:moduloResponse"/>
</operation>
</portType>
<binding name="CalculadoraPortBinding" type="tns:Calculadora">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="multiplicar">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="dividir">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="restar">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="sumar">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="hello">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="modulo">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="Calculadora">
<port name="CalculadoraPort" binding="tns:CalculadoraPortBinding">
<soap:address location="http://192.168.0.19:8080/WebServer/Calculadora"/>
</port>
</service>
</definitions>
PD:所有方法都返回Double对象,基本操作会收到2个数字,它们是Double数据类型。
谢谢。