天天看點

WebService SOAP、Restful和HTTP(post/get)請求差別

web service(SOAP)

Webservice的一個最基本的目的就是提供在各個不同平台的不同應用系統的協同工作能力。

Web service 就是一個應用程式,它向外界暴露出一個能夠通過Web進行調用的API。

SOAP是一種簡單基于xml的輕量協定,使用者web上交換結構化資訊和類型資訊。

soap請求是HTTP POST的一個專用版本,遵循一種特殊的xml消息格式Content-type設定為: text/xml任何資料都可以xml化。

本文将通過一個簡單的示例講解和示範Android平台的Web Service開發。

Ksoap2-android簡介

在Android平台調用Web Service需要依賴于第三方類庫ksoap2,它是一個SOAP Web service用戶端開發包,主要用于資源受限制的Java環境如Applets或J2ME應用程式(CLDC/ CDC/MIDP)。認真讀完對ksoap2的介紹你會發現并沒有提及它應用于Android平台開發,沒錯,在Android平台中我們并不會直接使用ksoap2,而是使用ksoap2 android。KSoap2 Android 是Android平台上一個高效、輕量級的SOAP開發包,等同于Android平台上的KSoap2的移植版本。

  需要引入ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar
           
//WebService的命名空間
  static final String namespace = "http://impl.service.suncreate.com";
  //伺服器釋出的url
  static final String url = http://10.100.3.41/axis2/services/UploadService;
  final String methodName = "upload"; // 函數名
  final int sessionID = "111111";  //sessionID
  //建立HttpTransportSE對象,通過HttpTransportSE類的構造方法可以指定WebService的url
  HttpTransportSE transport = new HttpTransportSE(url);
  transport.debug = true;
  //指定WebService的命名空間和函數名
  SoapObject soapObject = new SoapObject(namespace, methodName);
  //設定調用方法參數的值
  soapObject.addProperty("sessionID", sessionID); //sessionID
  soapObject.addProperty("data", cds); //cds是需要傳遞的對象
  SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
  envelope.bodyOut = transport;
  envelope.setOutputSoapObject(soapObject);
  //使用call方法調用WebService方法
  transport.call(null, envelope);
  SoapObject sb = (SoapObject) envelope.bodyIn;
  String xmlMessage = sb.toString(); // 擷取從伺服器端傳回的XML字元串
           

Restful

REST(Representational State Transfer)一種輕量級的Web Service架構,可以完全通過HTTP協定實作。其實作和操作比SOAP和XML-RPC更為簡潔,還可以利用緩存Cache來提高響應速度,性能、效率和易用性上都優于SOAP協定。

REST架構對資源的操作包括擷取、建立、修改和删除資源的操作正好對應HTTP協定提供的GET、POST、PUT和DELETE方法(Verb)

Restful與SOAP的差別

安全性:SOAP會好于restful

效率和易用性(REST更勝一籌)

成熟度(總的來說SOAP在成熟度上優于REST)

HTTP-GET 和 HTTP-POST

HTTP-GET和HTTP-POST是标準協定,他們使用HTTP(超文本傳輸協定)謂詞(謂詞是指條件表達式的求值傳回真或假的過程。)對參數進行編碼并将參數作為名稱/值對傳遞,還使用關聯的請求語義。每個協定都包含一系列HTTP請求标頭,HTTP請求标頭及其他一些資訊定義用戶端向伺服器請求哪些内容,哪個伺服器用一系列HTTP響應标頭和所請求的資料進行響應。

HTTP-GET 使用 MIME 類型 application/x-www-form-urlencoded(将追加到處理請求的伺服器的 URL 中)以 URL 編碼文本的形式傳遞其參數。 URL 編碼是一種字元編碼形式,可確定傳遞的參數中包含一緻性文本,例如将空格編碼為 %20,其它符号轉換為%XX,其中XX為該符号以16進制表示的ASCII(或ISO Latin-1)值。 追加的參數也稱為查詢字元串。

與 HTTP-GET 類似,HTTP-POST 參數也是 URL 編碼的。 但是,名稱/值對是在實際的 HTTP 請求消息内部傳遞的,而不是作為 URL 的一部分進行傳遞。

我們日常網站、系統都是使用這種形式進行通路我們的應用程式。

package cn.roco.manage.service;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public class NewsService {

    public static final int POST = ;
    public static final int GET = ;
    public static final int HttpClientPost = ;

    /**
     * 儲存資料
     * 
     * @param title
     *            标題
     * @param length
     *            時長
     * @param flag
     *            true則使用POST請求 false使用GET請求
     * @return 是否儲存成功
     * @throws Exception
     */
    public static boolean save(String path, String title, String timelength,
            int flag) throws Exception {
        Map<String, String> params = new HashMap<String, String>();
        params.put("title", title);
        params.put("timelength", timelength);
        switch (flag) {
        case POST:
            return sendPOSTRequest(path, params, "UTF-8");
        case GET:
            return sendGETRequest(path, params, "UTF-8");
        case HttpClientPost:
            return sendHttpClientPOSTRequest(path, params, "UTF-8");
        }
        return false;
    }

    /**
     * 通過HttpClient架構發送POST請求
     * HttpClient該架構已經內建在android開發包中
     * 個人認為此架構封裝了很多的工具類,性能比不上自己手寫的下面兩個方法
     * 但是該方法可以提高程式員的開發速度,降低開發難度
     * @param path
     *            請求路徑
     * @param params
     *            請求參數
     * @param encoding
     *            編碼
     * @return 請求是否成功
     * @throws Exception
     */
    private static boolean sendHttpClientPOSTRequest(String path,
            Map<String, String> params, String encoding) throws Exception {
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();// 存放請求參數
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                //BasicNameValuePair實作了NameValuePair接口
                pairs.add(new BasicNameValuePair(entry.getKey(), entry
                        .getValue()));
            }
        }
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs, encoding);    //pairs:請求參數   encoding:編碼方式
        HttpPost httpPost = new HttpPost(path); //path:請求路徑
        httpPost.setEntity(entity); 

        DefaultHttpClient client = new DefaultHttpClient(); //相當于浏覽器
        HttpResponse response = client.execute(httpPost);  //相當于執行POST請求
        //取得狀态行中的狀态碼
        if (response.getStatusLine().getStatusCode() == ) {
            return true;
        }
        return false;
    }

    /**
     * 發送POST請求
     * 
     * @param path
     *            請求路徑
     * @param params
     *            請求參數
     * @param encoding
     *            編碼
     * @return 請求是否成功
     * @throws Exception
     */
    private static boolean sendPOSTRequest(String path,
            Map<String, String> params, String encoding) throws Exception {
        StringBuilder data = new StringBuilder();
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                data.append(entry.getKey()).append("=");
                data.append(URLEncoder.encode(entry.getValue(), encoding));// 編碼
                data.append('&');
            }
            data.deleteCharAt(data.length() - );
        }
        byte[] entity = data.toString().getBytes(); // 得到實體資料
        HttpURLConnection connection = (HttpURLConnection) new URL(path)
                .openConnection();
        connection.setConnectTimeout();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        connection.setRequestProperty("Content-Length",
                String.valueOf(entity.length));

        connection.setDoOutput(true);// 允許對外輸出資料
        OutputStream outputStream = connection.getOutputStream();
        outputStream.write(entity);

        if (connection.getResponseCode() == ) {
            return true;
        }
        return false;
    }

    /**
     * 發送GET請求
     * 
     * @param path
     *            請求路徑
     * @param params
     *            請求參數
     * @param encoding
     *            編碼
     * @return 請求是否成功
     * @throws Exception
     */
    private static boolean sendGETRequest(String path,
            Map<String, String> params, String encoding) throws Exception {
        StringBuilder url = new StringBuilder(path);
        url.append("?");
        for (Map.Entry<String, String> entry : params.entrySet()) {
            url.append(entry.getKey()).append("=");
            url.append(URLEncoder.encode(entry.getValue(), encoding));// 編碼
            url.append('&');
        }
        url.deleteCharAt(url.length() - );
        HttpURLConnection connection = (HttpURLConnection) new URL(
                url.toString()).openConnection();
        connection.setConnectTimeout();
        connection.setRequestMethod("GET");
        if (connection.getResponseCode() == ) {
            return true;
        }
        return false;
    }
}
           

SOAP與HTTP的差別

大多數對外接口會實作web service方法而不是http方法。

web service相對http (post/get)的好處

1.接口中實作的方法和要求參數一目了然

2.不用擔心大小寫問題

3.不用擔心中文urlencode問題

4.代碼中不用多次聲明認證(賬号,密碼)參數

5.傳遞參數可以為數組,對象等…

6.web service相對http(post/get)由于要進行xml解析,速度可能會有所降低。

7.web service 完全可以可以被http(post/get)替代,而且現在的開放平台都是用的HTTP(post/get)實作的。

繼續閱讀