Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android_WebServices_源碼分析

Android_WebServices_源碼分析

編輯:關於Android編程

本博文為子墨原創,轉載請注明出處! http://blog.csdn.net/zimo2013/article/details/38037989 在 Android_WebServices_介紹一文中,簡單介紹了WebServices的基礎知識,下面主要分析 ksoap2-android-assembly-3.3.0-jar-with-dependencies.jar實現源碼。

1.調用WebServices流程

public void getRemoteInfo(String phoneSec) {
	String nameSpace = "http://WebXml.com.cn/";
	String methodName = "getMobileCodeInfo";
	String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
	String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";

	// 1.初始化 SoapObject對象,為該方法設置參數,相當於信體
	SoapObject request = new SoapObject(nameSpace, methodName);
	request.addProperty("mobileCode", phoneSec);
	request.addProperty("userId", "");
	
	// 2.實例化SoapSerializationEnvelope對象,相當於信皮
	SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
	envelope.bodyOut = request;
	envelope.dotNet = true;//兼容.net開發的Net-Services

	// 3.實例化HttpTransportSE對象,還可以指定放了訪問的請求時間
	HttpTransportSE transport = new HttpTransportSE(endPoint);
	//HttpTransportSE transport = new HttpTransportSE(endPoint, timeout);
	try {
	// 4.核心方法調用,其中soapActon在SoapSerializationEnvelope.VER12時無效,且為POST請求
		transport.call(soapAction, envelope);
		
		SoapObject response = (SoapObject) envelope.bodyIn;
		final String result = response.getProperty(0).toString();//Vector
		toast(result);
	} catch (Exception e) {
		e.printStackTrace();
		toast(e.getMessage());
	}
}

2.transport.call關鍵源碼分析

/**
 * Perform a soap call with a given namespace and the given envelope providing
 * any extra headers that the user requires such as cookies. Headers that are
 * returned by the web service will be returned to the caller in the form of a
 * List of HeaderProperty instances.
 *
 * @param soapAction
 *            the namespace with which to perform the call in.
 * @param envelope
 *            the envelope the contains the information for the call.
 * @param headers
 *   List of HeaderProperty headers to send with the SOAP request.
 * @param outputFile
 *              a file to stream the response into rather than parsing it, streaming happens when file is not null
 *
 * @return Headers returned by the web service as a List of
 * HeaderProperty instances.
 *
 * @throws HttpResponseException
 *              an IOException when Http response code is different from 200
 */
public List call(String soapAction, SoapEnvelope envelope, List headers, File outputFile)
    throws HttpResponseException, IOException, XmlPullParserException {

    if (soapAction == null) {
        soapAction = "\"\"";
    }

    //根據envelope,將其序列化為一個請求字節數組
    byte[] requestData = createRequestData(envelope, "UTF-8");

    // debug=true, requestDump的值為請求的數據,方便調試
    requestDump = debug ? new String(requestData) : null;
    responseDump = null;

    //connection = new ServiceConnectionSE(proxy, url, timeout);包括設置時間
    ServiceConnection connection = getServiceConnection();

    connection.setRequestProperty("User-Agent", USER_AGENT);
    // SOAPAction is not a valid header for VER12 so do not add
    // it
    // @see "http://code.google.com/p/ksoap2-android/issues/detail?id=67
    if (envelope.version != SoapSerializationEnvelope.VER12) {
        connection.setRequestProperty("SOAPAction", soapAction);
    }

    if (envelope.version == SoapSerializationEnvelope.VER12) {
        connection.setRequestProperty("Content-Type", CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8);
    } else {
        connection.setRequestProperty("Content-Type", CONTENT_TYPE_XML_CHARSET_UTF_8);
    }

    // this seems to cause issues so we are removing it
    //connection.setRequestProperty("Connection", "close");
    connection.setRequestProperty("Accept-Encoding", "gzip");


    // Pass the headers provided by the user along with the call
    if (headers != null) {
        for (int i = 0; i < headers.size(); i++) {
            HeaderProperty hp = (HeaderProperty) headers.get(i);
            connection.setRequestProperty(hp.getKey(), hp.getValue());
        }
    }

    // POST請求
    connection.setRequestMethod("POST");
    //發送數據,耗時較長,將requestData發送至connection的輸出流
    sendData(requestData, connection, envelope);
    
    requestData = null;
    InputStream is = null;
    List retHeaders = null;
    byte[] buf = null; // To allow releasing the resource after used
    int contentLength = 8192; // To determine the size of the response and adjust buffer size
    boolean gZippedContent = false;
    boolean xmlContent = false;
    // 得到響應碼
    int status = connection.getResponseCode();

    try {
    	//得到響應頭
        retHeaders = connection.getResponseProperties();

        for (int i = 0; i < retHeaders.size(); i++) {
            HeaderProperty hp = (HeaderProperty)retHeaders.get(i);
            // HTTP response code has null key
            if (null == hp.getKey()) {
                continue;
            }

            // If we know the size of the response, we should use the size to initiate vars
            if (hp.getKey().equalsIgnoreCase("content-length") ) {
                if ( hp.getValue() != null ) {
                    try {
                        contentLength = Integer.parseInt( hp.getValue() );
                    } catch ( NumberFormatException nfe ) {
                        contentLength = 8192;
                    }
                }
            }

            // Check the content-type header to see if we're getting back XML, in case of a
            // SOAP fault on 500 codes
            if (hp.getKey().equalsIgnoreCase("Content-Type")
                    && hp.getValue().contains("xml")) {
                xmlContent = true;
            }


            // ignoring case since users found that all smaller case is used on some server
            // and even if it is wrong according to spec, we rather have it work..
            if (hp.getKey().equalsIgnoreCase("Content-Encoding")
                 && hp.getValue().equalsIgnoreCase("gzip")) {
                gZippedContent = true;
            }
        }

        //first check the response code....
        if (status != 200) {
            //throw new IOException("HTTP request failed, HTTP status: " + status);
            throw new HttpResponseException("HTTP request failed, HTTP status: " + status, status);
        }

        if (contentLength > 0) {
            if (gZippedContent) {
                is = getUnZippedInputStream(
                        new BufferedInputStream(connection.openInputStream(),contentLength));
            } else {
                is = new BufferedInputStream(connection.openInputStream(),contentLength);
            }
        }
    } catch (IOException e) {
        if (contentLength > 0) {
            if(gZippedContent) {
                is = getUnZippedInputStream(
                        new BufferedInputStream(connection.getErrorStream(),contentLength));
            } else {
                is = new BufferedInputStream(connection.getErrorStream(),contentLength);
            }
        }

        if ( e instanceof HttpResponseException) {
            if (!xmlContent) {
                if (debug && is != null) {
                    //go ahead and read the error stream into the debug buffers/file if needed.
                    readDebug(is, contentLength, outputFile);
                }

                //we never want to drop through to attempting to parse the HTTP error stream as a SOAP response.
                connection.disconnect();
                throw e;
            }
        }
    }

    // debug=true responseDump=響應數據,方便調試
    if (debug) {
        is = readDebug(is, contentLength, outputFile);
    }

    // 根據is流,將流數據解析至 envelope.bodyIn中去
    parseResponse(envelope, is,retHeaders);

    //釋放資源
    is = null;
    buf = null;
    connection.disconnect();
    connection = null;
    // 返回響應頭
    return retHeaders;
}

實例下載http://download.csdn.net/detail/strawberry2013/7663399

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved