[java] 如何在Android上调用SOAP Web服务



Answers

org.apache.http.impl.client.DefaultHttpClient默认进入Android SDK。 这会让你连接到WSDL。

HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://www.example.com/" + URL);
HttpResponse response = httpClient.execute(httpGet, localContext);
Question

我很难找到有关如何使用Android调用标准SOAP / WSDL Web服务的良好信息。 我所能找到的都是非常复杂的文档和对“kSoap2”的引用,然后关于用SAX手动解析它的一些内容。 好吧,没关系,但是它是2008年的,所以我认为应该有一些用于调用标准Web服务的好库。

Web服务基本上是在NetBeans创建的。 我希望IDE支持生成管道类。 我只需要以最简单/最优雅的方式联系基于Android的手机的基于WSDL的Web服务。




要从android调用SOAP Web Service,请尝试使用此客户端

不要忘记在你的java构建路径中添加ksoap2-android.jar

public class WsClient {
    private static final String SOAP_ACTION = "somme";
    private static final String OPERATION_NAME = "somme";
    private static final String WSDL_TARGET_NAMESPACE = "http://example.ws";
    private static final String SOAP_ADDRESS = "http://192.168.1.2:8080/axis2/services/Calculatrice?wsdl";

    public String caclculerSomme() {

        String res = null;
        SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE,
                OPERATION_NAME);
        request.addProperty("a", "5");
        request.addProperty("b", "2");

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS);

        try {
            httpTransport.call(SOAP_ACTION, envelope);
            String result = envelope.getResponse().toString();
            res = result;
            System.out.println("############# resull is :" + result);
        } catch (Exception exception) {
            System.out.println("########### ERRER" + exception.getMessage());
        }

        return res;
    }
}



我会建议检查一个非常有用的工具,这对我有很大的帮助。 照顾这个项目的人也非常有帮助。 www.wsdl2code.com/




大约一年前,我正在阅读本主题,试图弄清楚如何在Android上进行SOAP调用 - 使用HttpClient构建自己的建议导致我为Android构建自己的SOAP库:

IceSoap

基本上它允许你通过一个简单的Java API建立信封发送,然后自动将它们解析成你通过XPath定义的对象......例如:

<Dictionary>
    <Id></Id>
    <Name></Name>
</Dictionary>

变为:

@XMLObject("//Dictionary")
public class Dictionary {
    @XMLField("Id")
    private String id;

    @XMLField("Name")
    private String name;
}

我将它用于自己的项目,但我认为它可以帮助其他人,所以我花了一些时间将它分离出来并记录下来。 我真的很喜欢它,如果你的一些可怜的灵魂在谷歌搜索“SOAP Android”的时候偶然发现,它可能会给它带来一些好处。




我为Android平台创建了一个新的SOAP客户端。 它使用JAX-WS生成的接口,但它迄今只是一个概念验证。

如果您有兴趣,请尝试示例和/或在AndroidSOAP观看源代码。




这是一个在android中使用SOAP Web服务的工作示例。

**注意:***请勿忘记在您的项目中添加ksoap2.jar,并在AndroidManifest文件中添加INTERNET权限*

public final String WSDL_TARGET_NAMESPACE = "http://tempuri.org/";
public final String METHOD_NAME = "FahrenheitToCelsius";
public final String PROPERTY_NAME = "Fahrenheit";
public final String SOAP_ACTION = "http://tempuri.org/FahrenheitToCelsius";
public final String SOAP_ADDRESS = "http://www.w3schools.com/webservices/tempconvert.asmx";


private class TestAsynk extends AsyncTask<String, Void, String> {

    @Override
    protected void onPostExecute(String result) {

        super.onPostExecute(result);
        Toast.makeText(getApplicationContext(),
                String.format("%.2f", Float.parseFloat(result)),
                Toast.LENGTH_SHORT).show();
    }

    @Override
    protected String doInBackground(String... params) {
        SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE,
                METHOD_NAME);
        request.addProperty(PROPERTY_NAME, params[0]);

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.dotNet = true;

        envelope.setOutputSoapObject(request);

        HttpTransportSE androidHttpTransport = new HttpTransportSE(
                SOAP_ADDRESS);
        Object response = null;
        try {

            androidHttpTransport.call(SOAP_ACTION, envelope);
            response = envelope.getResponse();
            Log.e("Object response", response.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return response.toString();
    }
}



我和KSOAP有过约谈。 我选择了一个相对简单的方法。

给定一个WSDL文件,为每个请求创建SOAP请求模板(例如:使用SOAP UI),然后将这些值替换为代码中传递的值。 使用DefaultHttpClient实例将此数据发布到服务端点并获取响应流。 使用XML Pull解析器解析响应流。




添加Soap Libaray( ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar ):

public static String Fn_Confirm_CollectMoney_Approval(

        HashMap < String, String > str1,
        HashMap < String, String > str2,
        HashMap < String, String > str3) {

    Object response = null;
    String METHOD_NAME = "CollectMoney";
    String NAMESPACE = "http://xxx/yyy/xxx";
    String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
    String SOAP_ACTION = "";

    try {

        SoapObject RequestParent = new SoapObject(NAMESPACE, METHOD_NAME);

        SoapObject Request1 = new SoapObject(NAMESPACE, "req");

        PropertyInfo pi = new PropertyInfo();

        Set mapSet1 = (Set) str1.entrySet();

        Iterator mapIterator1 = mapSet1.iterator();

        while (mapIterator1.hasNext()) {

            Map.Entry mapEntry = (Map.Entry) mapIterator1.next();

            String keyValue = (String) mapEntry.getKey();

            String value = (String) mapEntry.getValue();

            pi = new PropertyInfo();

            pi.setNamespace("java:com.xxx");

            pi.setName(keyValue);

            pi.setValue(value);

            Request1.addProperty(pi);
        }

        mapSet1 = (Set) str3.entrySet();

        mapIterator1 = mapSet1.iterator();

        while (mapIterator1.hasNext()) {

            Map.Entry mapEntry = (Map.Entry) mapIterator1.next();

            // getKey Method of HashMap access a key of map
            String keyValue = (String) mapEntry.getKey();

            // getValue method returns corresponding key's value
            String value = (String) mapEntry.getValue();

            pi = new PropertyInfo();

            pi.setNamespace("java:com.xxx");

            pi.setName(keyValue);

            pi.setValue(value);

            Request1.addProperty(pi);
        }

        SoapObject HeaderRequest = new SoapObject(NAMESPACE, "XXX");

        Set mapSet = (Set) str2.entrySet();

        Iterator mapIterator = mapSet.iterator();

        while (mapIterator.hasNext()) {

            Map.Entry mapEntry = (Map.Entry) mapIterator.next();

            // getKey Method of HashMap access a key of map
            String keyValue = (String) mapEntry.getKey();

            // getValue method returns corresponding key's value
            String value = (String) mapEntry.getValue();

            pi = new PropertyInfo();

            pi.setNamespace("java:com.xxx");

            pi.setName(keyValue);

            pi.setValue(value);

            HeaderRequest.addProperty(pi);
        }

        Request1.addSoapObject(HeaderRequest);

        RequestParent.addSoapObject(Request1);

        SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER10);

        soapEnvelope.dotNet = false;

        soapEnvelope.setOutputSoapObject(RequestParent);

        HttpTransportSE transport = new HttpTransportSE(URL, 120000);

        transport.debug = true;

        transport.call(SOAP_ACTION, soapEnvelope);

        response = (Object) soapEnvelope.getResponse();

        int cols = ((SoapObject) response).getPropertyCount();

        Object objectResponse = (Object) ((SoapObject) response)
                .getProperty("Resp");

        SoapObject subObject_Resp = (SoapObject) objectResponse;


        modelObject = new ResposeXmlModel();

        String MsgId = subObject_Resp.getProperty("MsgId").toString();


        modelObject.setMsgId(MsgId);

        String OrgId = subObject_Resp.getProperty("OrgId").toString();


        modelObject.setOrgId(OrgId);

        String ResCode = subObject_Resp.getProperty("ResCode").toString();


        modelObject.setResCode(ResCode);

        String ResDesc = subObject_Resp.getProperty("ResDesc").toString();


        modelObject.setResDesc(ResDesc);

        String TimeStamp = subObject_Resp.getProperty("TimeStamp")
                .toString();


        modelObject.setTimestamp(ResDesc);

        return response.toString();

    } catch (Exception ex) {

        ex.printStackTrace();

        return null;
    }

}



几个月前,我在j2ee应用程序中使用jax-ws web服务,在那里我们使用CXF wsdl2java从WSDL文件中生成WS客户端存根,并使用这些客户端存根来使用Web服务。 几个星期前,当我试图在Android平台上以相同的方式使用Web服务时,我无法使用Web服务,因为Android jar并不是所有支持其中的类的“jax-ws”。 那次我没有找到任何这样的工具(如果我没有失败谷歌效率),以满足我的要求 -

  • 从WSDL获取客户端存根。
  • 并用一些参数(java业务请求对象)调用服务。
  • 获取响应业务对象。

所以,我开发了我自己的Android SOAP客户端生成工具 。 你必须遵循以下步骤:

  • 从WSDL获取WS客户端存根,将其放入您的项目中。
  • 说一些服务“ComplexOperationService”,实例化服务,获取端点端口并调用服务方法,并从Web服务获取响应:

例如:

ComplexOperationService service = new ComplexOperationService( );
ComplexOperation port= service.getComplexOperationPort();    
SomeComplexRequest request = --Get some complex request----;    
SomeComplexResp resp = port.operate( request  );
  • 您不需要关心服务类/ req / response类或任何其他类以及方法,因为您知道它们都是从WSDL生成的。
  • 当然,你不需要知道soap action / envelop / namespace等。只需要像开发者一样调用方法。









要从移动设备(特别是在Android手机上)调用Web服务,我已经使用了一种非常简单的方法来实现它。 我尚未使用任何Web服务客户端API尝试调用Web服务。 我的方法如下拨打电话。

  1. 使用Java标准API HttpURLConnection创建一个简单的HTTP连接。
  2. 形成一个SOAP请求。 (您可以帮助SOAPUI进行SOAP请求。)
  3. 将doOutPut标志设置为true。
  4. 设置HTTP标头值,如内容长度,内容类型和用户代理。 不要忘记设置内容长度值,因为它是必需的。
  5. 将整个SOAP请求写入输出流。
  6. 调用方法来建立连接并接收响应(在我的情况下,我使用getResonseCode )。
  7. 如果您收到的回复代码为
    1. 这意味着您已成功调用Web服务。
  8. 现在在同一个HTTP连接上获取输入流并接收字符串对象。 这个字符串对象是一个SOAP响应。
  9. 如果响应代码不是200,则在相同的HTTP ErrorInput上采用ErrorInput流,并接收错误(如果有)。
  10. 使用SAXParser(在我的情况下)或DOMParaser或任何其他解析机制解析收到的响应。

我已经为Android手机实施了此过程,并且它已成功运行。 即使超过700 KB,我也能够解析响应。




调用ksoap2方法。 它工作得很好。

设置细节,如

private static String mNAMESPACE=null;
private static String mURL=null;
public static Context context=null;
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);

envelope.addMapping(mNAMESPACE, "UserCredentials",new UserCredendtials().getClass());
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(mURL);

然后才能得到结果

androidHttpTransport.call(SOAP_ACTION, envelope);
result = (SoapPrimitive)envelope.getResponse();



Related