将XML文件添加到SOAP请求

时间:2014-07-07 09:32:06

标签: android xml soap ksoap2

(我想打招呼,但网站一直在删除oO)......! 这是我的问题:我发现如何使用kso​​ap向webservice发送请求,但我仍然无法确定将XML添加到请求的位置! 这是我的代码:

    public static SoapObject soap () throws IOException, XmlPullParserException {
    SoapObject request = new SoapObject (NAMESPACE, METHOD_NAME);

    /* HERE IS THE PROBLEM */
    request.addProperty(toto, HERE IS MY XML);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope (
            SoapEnvelope.VER11);
    envelope.setOutputSoapObject (request);
    HttpTransportSE androidHttpTransport = new HttpTransportSE (URL);
    androidHttpTransport.debug = true; 
    androidHttpTransport.call (SOAP_ACTION, envelope);
    SoapObject soapResult = (SoapObject) envelope.getResponse ();
    return soapResult;
}

如果我删除“request.addProperty line”,它会到达服务器,但它什么都不做,因为我需要发送我的XML。如果有人知道如何做到这一点,那肯定会成为我的一天!!

感谢您阅读本文!

2 个答案:

答案 0 :(得分:0)

也许它对这个特定问题没有帮助,但我不建议使用kso​​ap。我浪费了太多时间去工作,之后我用几个小时写了我的SOAP客户端,它没有问题。

很简单:

public static HashMap<String, Object> callSOAPServer(StringBuffer soap /* YOUR XML GOES HERE*/,String action) {
    HashMap<String, Object> xMap = new HashMap<String, Object>(); 
    byte[] result = null;              
    byte[] data = new byte[1024*1024];  
    HttpClient httpclient = new DefaultHttpClient(); /* Your probably need to edit client for your needs, like timeout, scheme, etc */
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    DataInputStream is = null;
    boolean download = true;
    HttpPost httppost = new HttpPost(/* YOUR URL GOES HERE */ );
    httppost.setHeader("soapaction", action);
    httppost.setHeader("Content-Type", "text/xml; charset=utf-8");     
    try {               
         HttpEntity entity = new StringEntity(soap.toString(),HTTP.UTF_8);
         httppost.setEntity(entity);  
         HttpResponse response = httpclient.execute(httppost);
         HttpEntity r_entity = response.getEntity();
         if (r_entity != null) {                    
             result = new byte[(int) r_entity.getContentLength()];      
             size = result.length;                 
             if (r_entity.isStreaming()) {                      
                is = new DataInputStream(r_entity.getContent());     
                while((count = is.read(data, 0, data.length)) != -1) {                      
                        buffer.write(data, 0, count);
                        total +=count;                    
                    }
             }
             buffer.flush();
             result = buffer.toByteArray();
             data = null;
             buffer = null;                
          }             
     } catch (Exception e) {
             e.printStackTrace();
            result = null;
     }          
     if(result !=null){             
        try {
            String sb;
            String sn;              
            sb = new String(result, "UTF-8");
            sn = sb.replace("&amp;", "AMP"); //Precaution for SAX parser
            result = sn.getBytes();     
        } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
        } 
            xMap.put(STATUS, "OK");
            xMap.put(SOAP, result);        
        }else{
            if(xMap.get(STATUS) == null) {
                xMap.put(STATUS, "ERROR");
            }   
        }           
        httpclient.getConnectionManager().shutdown(); 
        return xMap;        
  }

这是解析器:

public ArrayList< HashMap<String,String>> parseSoap (byte[] soapResult,String soapFunctionName, String... args) {       
        ArrayList< HashMap<String,String>> xMap = new ArrayList< HashMap<String,String>>();         
        if(soapResult == null) xMap.put(STATUS, "Where is stuff to handle");
        byte[] initReqrepsonse = soapResult;
        ByteArrayInputStream bais = new ByteArrayInputStream(initReqrepsonse);

        SAXParserFactory spf = SAXParserFactory.newInstance();
        try {
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();

            if(soapFunctionName.equals(NEWS)) { /*IF YOU USE MULTIPLE SOAP FUNCTION, YOU NEED TO DETERMINE WHICH IS WHICH...*/
               NewsXMLHandler myXMLHandler = new NewsXMLHandler(); /*..BECAUSE HERE YOU NEED TO SPECIFY FIELDS WHICH YOU WANT TO RETRIEVE FROM XML*/
               xr.setContentHandler(myXMLHandler);
               xr.parse(new InputSource(bais));
               xMap.put(SOAP_OUTPUT, myXMLHandler.getOutput());
               myXMLHandler = null;
             }
             sp = null;
             xr = null;
             } catch (Exception e) {
                e.printStackTrace();
             }
          spf = null;
      return xMap;
 }

对于那个确定要解析哪些字段的东西(NewsXMLHandler):

public class NewsXMLHandler extends DefaultHandler {

public NewsXMLHandler() {}

private ArrayList< HashMap<String,String> > data;   

private HashMap<String,String> dataHash;

private final StringBuilder mStringBuilder = new StringBuilder();

private boolean bStore = false;

ArrayList< HashMap<String,String>>  getOutput() {
    return data;
}


@Override
public void startDocument() throws SAXException 
{
    data = new ArrayList< HashMap<String,String> >();

}

@Override
public void endDocument() throws SAXException
{

}

@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
    mStringBuilder.setLength(0);
    bStore = true;      
    try { 
        //HERE YOU NEED TO SPECIFY WHICH IS ROOT NODE OF XML FROM SOAP, IN MY EXPERIENCE ITS OUT
          if(localName.equalsIgnoreCase("out")) {
             dataHash = new HashMap<String,String>();
         }          

    } catch (Exception e) 
    {
        Log.d("error in startElement", e.getStackTrace().toString());
    }
}
@Override

public void endElement(String namespaceURI, String localName, String qName) throws SAXException 
{
        bStore = false;         

        //HERE IT IS, JUST WRITE NAME OF NODE WHICH YOU WANT TO USE FOR YOUR APPLICATION        
        if (localName.equalsIgnoreCase("your node name"))
        {               
            dataHash.put("your node name", mStringBuilder.toString().trim());           
        }

        if (localName.equalsIgnoreCase("your node name 2"))
        {               
            dataHash.put("your node name 2", mStringBuilder.toString().trim());         
        }

        // CONTINUE WITH THOSE IFS UNTIL YOU HAVE ALL FIELDS WHICH YOU NEED COVERED

        // HERE YOU WRAP ALL OF THOSE HIGHER NODE AND SAVE TO ARRAYLIST, SO IF THERE ARE MORE OF THEM, YOU GET THEM ALL - AGAIN ITS NAME OF ROOT NODE 
        if(localName.equalsIgnoreCase("out")) {
            data.add(dataHash);
            dataHash = null;
        } 

}
@Override

public void characters(char ch[], int start, int length)
{

    if (bStore) 
    {   
        mStringBuilder.append(ch, start, length);
        if(mStringBuilder.length() == 0)  mStringBuilder.setLength(0);            

    }
}
}

这就是用法。您似乎已经想到了,您无法在主线程上执行URL请求。您只需要使用AsyncTask,Service,IntentService等。我不打算在此处介绍它。我喜欢使用IntentService并将条目保存到数据库。

让我们假设您在SOAPHandler类中包装这两个静态函数:

HashMap<String, Object> SOAPResponse = SOAPHandler.callSOAPSERVER(/*YOUR XML REQUEST HERE*/, /*NAME OF SOAP METHOD ON SERVER*/)
ArrayList< HashMap<String,String>> parsedEntries = SOAPHandler.parseSoap(SOAPResponse, NEWS, NULL);

foreach(HashMap<String,String> hash : parsedEntries) {
       String entryOne = hash.get("your node name");
       String entryTwo = hash.get("your node name 2");
       //HERE YOU HAVE YOUR STRINGS, DO WHATEVER WITH THEM
}

答案 1 :(得分:0)

以下是Basic KSOAP Android tutorial,这有助于了解如何使用KSOAP来使用网络服务。

重要的是要注意,您将无法使用KSOAP发送原始xml数据包,但需要将参数作为PropertyInfo类实例传递。

HTH