在瀏覽器裡頭有實做AJAX query,這讓網頁有了更大的發揮空間,

程式人員可以讓網頁就像一般應用程式一樣有趣。

那如果,一般應用程式也可以發出HTTP query,

進而取得web service吐出的東西,那又會擦出怎樣的火花呢? 先賣個關子~

本篇只講在Android上,要如何寫一個發出HTTP query,又接回HTTP response的程式。

關鍵字:Android & HttpClient

在Android SDK裡有引入org.apache.http.client,

這package是這程式的靈魂,詳情可以看本篇的參考。

底下是程式:

流程:
1.建一個text view

2.呼叫HTTPGetQuery

2.1.建一個HTTP client

2.2.建一個HTTP get物件,並在初始化的參數帶入URL

2.3.建一個HTTP reponse handler物件

2.4.HTTP client實際對web service query,並帶入HTTP get

2.5.取回reponse,再從response取出status code、header、cookie、content字串

2.6.因為HTTP是socket IO,所以用try catch包起來,以防IO錯誤時沒有處理到

2.7.回傳結果

3.將結果放到text view

4.畫出這個程式畫面

程式碼:

package androidajax.example.android;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

public class AndroidAJAX extends Activity {
    private Document xmldoc;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Have a text view on the scene.
        TextView tv = new TextView(this);
        // Put the answer string returned by the HTTP query on the scene.
        // Change the red url by yourself.
        Map map = HTTPGetQuery("http://test.com.url?account=牛蛙");
        //Map map = HTTPPostQuery("http://test.com.url");
        tv.setText(map.get("status").toString() + ": " + map.get("content").toString());
        // Render the scene.
        setContentView(tv);
    }
    
    /** Method: Do the HTTP query according to hostURL with "get" method. */
    private Map<String, String> HTTPGetQuery(String hostURL) {
        // Declare a content string prepared for returning.
        String content = "";
        // Have an HTTP client to connect to the web service.
        HttpClient httpClient = new DefaultHttpClient();
        // Have an HTTP response container.
        HttpResponse httpResponse = null;
        // Have map container to store the information.
        Map<String, String> map = new HashMap<String, String>();
        
        // This try & catch is prepared for the IO exception in case.
        try {
            // Have a post method class with the query URL.
            HttpGet httpQuery = new HttpGet(hostURL);
            // The HTTP client do the query and have the string type response.
            httpResponse = httpClient.execute(httpQuery);
            
            // Read the HTTP headers and into content.
            //for (Header header : httpResponse.getAllHeaders()) {
            //     content += "\n" + header.toString();
            //}
            // Read the HTTP response content as an encoded string.
            content += EntityUtils.toString(httpResponse.getEntity());
        }
        // Catch the HTTP exception.
        catch(ClientProtocolException ex) {
            content = "ClientProtocolException:" + ex.getMessage();
        }
        // Catch the any IO exception.
        catch(IOException ex) {
            content = "IOException:" + ex.getMessage();
        }
        // The HTTP connection must be closed any way.
        finally    {
            httpClient.getConnectionManager().shutdown();
        }
        
        // Check the HTTP connection is executed or not.
        if (httpResponse != null) {
            // Put the status code with status key.
            map.put("status", Integer.toString(httpResponse.getStatusLine().getStatusCode()));
            // Put the response content with content key
            map.put("content", content);
        }
        else {
            // Put the dummy with status key.
            map.put("status", "");
            // Put the dummy with content key
            map.put("content", "");
        }
        
        // Return result.
        return map;
    }
    
    /** Method: Do the HTTP query according to hostURL with "post" method. */
    private Map<String, String> HTTPPostQuery(String hostURL) {
        // Declare a content string prepared for returning.
        String content = "";
        // Have an HTTP client to connect to the web service.
        HttpClient httpClient = new DefaultHttpClient();
        // Have an HTTP response container.
        HttpResponse httpResponse = null;
        // Have map container to store the information.
        Map<String, String> map = new HashMap<String, String>();
        
        // This try & catch is prepared for the IO exception in case.
        try {
            // Have a post method class with the query URL.
            HttpPost httpQuery = new HttpPost(hostURL);
            
            // Have a list of key-value pair container.
            List<NameValuePair> pairs = new ArrayList<NameValuePair>();
            // Add the HTTP post arguments into the list.
            pairs.add(new BasicNameValuePair("account", "青蛙"));
            pairs.add(new BasicNameValuePair("password", "frog"));
            // Assign the list as the arguments of post being UTF_8 encoding.
            httpQuery.setEntity(new UrlEncodedFormEntity(pairs, HTTP.UTF_8));
            
            // The HTTP client do the query and have the string type response.
            httpResponse = httpClient.execute(httpQuery);
            
            // Read the HTTP response content as an encoded string.
            content += EntityUtils.toString(httpResponse.getEntity());
        }
        // Catch the HTTP exception.
        catch(ClientProtocolException ex) {
            content = "ClientProtocolException:" + ex.getMessage();
        }
        // Catch the any IO exception.
        catch(IOException ex) {
            content = "IOException:" + ex.getMessage();
        }
        // The HTTP connection must be closed any way.
        finally    {
            httpClient.getConnectionManager().shutdown();
        }
        
        // Check the HTTP connection is executed or not.
        if (httpResponse != null) {
            // Put the status code with status key.
            map.put("status", Integer.toString(httpResponse.getStatusLine().getStatusCode()));
            // Put the response content with content key.
            map.put("content", content);
        }
        else {
            // Put the dummy with status key.
            map.put("status", "");
            // Put the dummy with content key.
            map.put("content", "");
        }
        
        // Return result.
        return map;
    }
}

因為用到HTTP client,這會需要用到網路IO,需要權限授權,

所以要改 res/AndroidManifest.xml

我在</APPLICATION>下加上:
    <uses-permission android:name="android.permission.INTERNET" />

參考:
Android 上的 HTTP 服務相關函式:
    http://ysl-paradise.blogspot.com/2008/09/android-http-i.html
    http://ysl-paradise.blogspot.com/2008/09/android-http-ii.html
    http://ysl-paradise.blogspot.com/2008/09/android-http-iii.html

HttpClient Examples:
    http://hc.apache.org/httpcomponents-client-ga/examples.html
    http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientWithResponseHandler.java

Permission denied error while call webservice using HTTP in android:
    http://stackoverflow.com/questions/3932129/permission-denied-error-while-call-webservice-using-http-in-android-application

 

本文取自 http://blog.xuite.net/zack_pan/blog/47887919

 


arrow
arrow

    Frank 發表在 痞客邦 留言(0) 人氣()