關於Android網絡請求

Android應用經常會和服務器端交互,這就需要手機客戶端發送網絡請求。

1.網絡請求方式

最基本的方法有4種,分別是GET,POST,PUT,DELETE。常用的兩種網絡請求方式是POST,GET。下面我們要先知道 POST與GET請求方式的區別

⑴ 根據HTTP規範,GET用於信息獲取,POST表示可能修改變服務器上的資源的請求。是向服務器傳送數據。


⑵ GET請求的數據會附在URL之後(就是把數據放置在HTTP協議頭中),以?分割URL和傳輸數據,參數之間以&相連,值和表單內的各個字段一一對應。如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果數據是英文字母/數字,原樣發送,如果是空格,轉換爲+,如果是中文/其他字符,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX爲該符號以16進製表示的ASCII。在URL中是可以看到的。POST把提交的數據則放置在是HTTP包的包體中。用戶是看不到這個過程的。


⑶ GET方式提交的數據最多隻能是1024字節,理論上POST沒有限制,可傳較大量的數據。IIS4中最大爲80KB,IIS5中爲100KB?

這句話很多地方是這樣寫的,但是有些人認爲這種說法是錯誤的。他們是這樣說的:

.首先是"GET方式提交的數據最多隻能是1024字節",因爲GET是通過URL提交數據,那麼GET可提交的數據量就跟URL的長度有直接關係了。而實際上,URL不存在參數上限的問題HTTP協議規範沒有對URL長度進行限制。這個限制是特定的瀏覽器及服務器對它的限制。IE對URL長度的限制是2083字節(2K+35)。對於其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決於操作系統的支持。(注意這是限制是整個URL長度,而不僅僅是你的參數值數據長度。)

.理論上講,POST是沒有大小限制的HTTP協議規範也沒有進行大小限制,說“POST數據量存在80K/100K的大小限制”是不準確的,POST數據是沒有限制的,起限制作用的是服務器的處理程序的處理能力。對於ASP程序,Request對象處理每個表單域時存在100K的數據長度限制。但如果使用Request.BinaryRead則沒有這個限制。由這個延伸出去,對於IIS 6.0,微軟出於安全考慮,加大了限制。I

IS 6.0之前沒有這些限制。我們還需要注意:

1).IIS 6.0默認ASP POST數據量最大爲200KB,每個表單域限制是100KB。

2).IIS 6.0默認上傳文件的最大大小是4MB。

3).IIS 6.0默認最大請求頭是16KB。

所以上面的80K,100K可能只是默認值而已(注:關於IIS4和IIS5的參數,我還沒有確認),但肯定是可以自己設置的。由於每個版本的IIS對這些參數的默認值都不一樣,具體請參考相關的IIS配置文檔。


GET安全性較低低,但是執行效率卻比POST方法好。比如:通過GET提交數據,用戶名和密碼將明文出現在URL上。POST安全性較高。


2.網絡請求接口

⑴ HttpURLConnection接口

HttpURLConnection是繼承於URLConnection類,二者都是抽象類。其對象主要通過URL的openConnection方法獲得。

創建方法如下代碼所示:

URL url = new URL("http://www.51cto.com/index.jsp?par=123456");  
HttpURLConnection urlConn=(HttpURLConnection)url.openConnection(); 


通過以下方法可以對請求的屬性進行一些設置,如下所示

//設置輸入和輸出流  
urlConn.setDoOutput(true);  
urlConn.setDoInput(true);  
//設置請求方式爲POST  
urlConn.setRequestMethod("POST");  
//POST請求不能使用緩存  
urlConn.setUseCaches(false); 
//關閉連接  
urlConn.disConnection(); 

HttpURLConnection默認使用GET方式,例如下面代碼所示:

//以Get方式上傳參數
public class Activity03 extends Activity
{
	private final String DEBUG_TAG = "Activity03"; 
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);	
		TextView mTextView = (TextView)this.findViewById(R.id.TextView_HTTP);
		//http地址"?par=abcdefg"是我們上傳的參數
		String httpUrl = "http://192.168.1.110:8080/httpget.jsp?par=abcdefg";
		//獲得的數據
		String resultData = "";
		URL url = null;
		try
		{
			//構造一個URL對象
			url = new URL(httpUrl); 
		}
		catch (MalformedURLException e)
		{
			Log.e(DEBUG_TAG, "MalformedURLException");
		}
		if (url != null)
		{
			try
			{
				// 使用HttpURLConnection打開連接
				HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
				//得到讀取的內容(流)
				InputStreamReader in = new InputStreamReader(urlConn.getInputStream());
				// 爲輸出創建BufferedReader
				BufferedReader buffer = new BufferedReader(in);
				String inputLine = null;
				//使用循環來讀取獲得的數據
				while (((inputLine = buffer.readLine()) != null))
				{
					//我們在每一行後面加上一個"\n"來換行
					resultData += inputLine + "\n";
				}		  
				//關閉InputStreamReader
				in.close();
				//關閉http連接
				urlConn.disconnect();
				//設置顯示取得的內容
				if ( resultData != null )
				{
					mTextView.setText(resultData);
				}
				else 
				{
					mTextView.setText("讀取的內容爲NULL");
				}
			}
			catch (IOException e)
			{
				Log.e(DEBUG_TAG, "IOException");
			}
		}
		else
		{
			Log.e(DEBUG_TAG, "Url NULL");
		}
}

  如果需要使用POST方式,則需要setRequestMethod設置。代碼如下:

//以post方式上傳參數
public class Activity04  extends Activity
{
	private final String DEBUG_TAG = "Activity04"; 
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);
		
		TextView mTextView = (TextView)this.findViewById(R.id.TextView_HTTP);
		//http地址"?par=abcdefg"是我們上傳的參數
		String httpUrl = "http://192.168.1.110:8080/httpget.jsp";
		//獲得的數據
		String resultData = "";
		URL url = null;
		try
		{
			//構造一個URL對象
			url = new URL(httpUrl); 
		}
		catch (MalformedURLException e)
		{
			Log.e(DEBUG_TAG, "MalformedURLException");
		}
		if (url != null)
		{
			try
			{
				// 使用HttpURLConnection打開連接
				HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
				//因爲這個是post請求,設立需要設置爲true
				urlConn.setDoOutput(true);
				urlConn.setDoInput(true);
		        // 設置以POST方式
				urlConn.setRequestMethod("POST");
		        // Post 請求不能使用緩存
				urlConn.setUseCaches(false);
				urlConn.setInstanceFollowRedirects(true);
		        // 配置本次連接的Content-type,配置爲application/x-www-form-urlencoded的
				urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
		        // 連接,從postUrl.openConnection()至此的配置必須要在connect之前完成,
		        // 要注意的是connection.getOutputStream會隱含的進行connect。
				urlConn.connect();
				//DataOutputStream流
		        DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
		        //要上傳的參數
		        String content = "par=" + URLEncoder.encode("ABCDEFG", "gb2312");
		        //將要上傳的內容寫入流中
		        out.writeBytes(content); 
		        //刷新、關閉
		        out.flush();
		        out.close(); 
		        //獲取數據
		        BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
				String inputLine = null;
				//使用循環來讀取獲得的數據
				while (((inputLine = reader.readLine()) != null))
				{
					//我們在每一行後面加上一個"\n"來換行
					resultData += inputLine + "\n";
				}		  
				reader.close();
				//關閉http連接
				urlConn.disconnect();
				//設置顯示取得的內容
				if ( resultData != null )
				{
					mTextView.setText(resultData);
				}
				else 
				{
					mTextView.setText("讀取的內容爲NULL");
				}
			}
			catch (IOException e)
			{
				Log.e(DEBUG_TAG, "IOException");
			}
		}
		else
		{
			Log.e(DEBUG_TAG, "Url NULL");
		}
	}
}


⑵ HttpClient

Apache HttpClient 是一個開源項目,彌補了 java.net.* 靈活性不足的缺點,爲客戶端的HTTP編程提供高效、最新、功能豐富的工具包支持。

Android 平臺引入了 Apache HttpClient 的同時還提供了對它的一些封裝和擴展,例如設置缺省的HTTP超時和緩存大小等。

使用這部分接口的基本操作與 java.net.* 基本類似,主要包括: 創建 HttpClient 以及 GetMethod / PostMethod, HttpRequest 等對象,設置連接參數,執行HTTP操作,處理服務器返回結果。

//創建HttpClient

//這裏使用DefaultHttpClient表示默認屬性

HttpClient httpclient = new DefaultHttpClient();

Get方法的操作代碼示例如下所示:

public class Activity02 extends Activity
{
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);
		TextView mTextView = (TextView) this.findViewById(R.id.TextView_HTTP);
		// http地址
		String httpUrl = "http://192.168.1.110:8080/httpget.jsp?par=HttpClient_android_Get";
		//HttpGet連接對象
		HttpGet httpRequest = new HttpGet(httpUrl);
		try
		{
			//取得HttpClient對象
			HttpClient httpclient = new DefaultHttpClient();
			//請求HttpClient,取得HttpResponse
			HttpResponse httpResponse = httpclient.execute(httpRequest);
			//請求成功
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
			{
				//取得返回的字符串
				String strResult = EntityUtils.toString(httpResponse.getEntity());
				mTextView.setText(strResult);
			}
			else
			{
				mTextView.setText("請求錯誤!");
			}
		}
		catch (ClientProtocolException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (IOException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (Exception e)
		{
			mTextView.setText(e.getMessage().toString());
		}  
	
			}
}


  使用POST方法進行參數傳遞時,需要使用NameValuePair來保存要傳遞的參數,另外,還需要設置所使用的字符集。代碼如下所示:

public class Activity03 extends Activity
{
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);
		TextView mTextView = (TextView) this.findViewById(R.id.TextView_HTTP);
		// http地址
		String httpUrl = "http://192.168.1.110:8080/httpget.jsp";
		//HttpPost連接對象
		HttpPost httpRequest = new HttpPost(httpUrl);
		//使用NameValuePair來保存要傳遞的Post參數
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		//添加要傳遞的參數
		params.add(new BasicNameValuePair("par", "HttpClient_android_Post"));
		try
		{
			//設置字符集
			HttpEntity httpentity = new UrlEncodedFormEntity(params, "gb2312");
			//請求httpRequest
			httpRequest.setEntity(httpentity);
			//取得默認的HttpClient
			HttpClient httpclient = new DefaultHttpClient();
			//取得HttpResponse
			HttpResponse httpResponse = httpclient.execute(httpRequest);
			//HttpStatus.SC_OK表示連接成功
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
			{
				//取得返回的字符串
				String strResult = EntityUtils.toString(httpResponse.getEntity());
				mTextView.setText(strResult);
			}
			else
			{
				mTextView.setText("請求錯誤!");
			}
		}
		catch (ClientProtocolException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (IOException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (Exception e)
		{
			mTextView.setText(e.getMessage().toString());
		}  
	}
}

HttpClient實際上是對Java提供方法的一些封裝,在HttpURLConnection中的輸入輸出流操作,在這個接口中被統一封裝成了HttpPost(HttpGet)和HttpResponse,這樣,就減少了操作的繁瑣性。

另外,在使用POST方式進行傳輸時,需要進行字符編碼。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章