1. 程式人生 > >Android連線Tomcat伺服器

Android連線Tomcat伺服器

在保證伺服器是正常狀態時,將從Android模擬器上傳送請求給服務端並接收服務端返回來的響應。

保證HttpServlet配置正常。可以通過在瀏覽器輸入配置的地址,若能正常響應,那麼在Android中去請求的話也是能正常響應的。

這裡列舉的Demo是在activity中有兩個按鈕,分別執行get請求和post請求的同時傳遞引數到服務端,並將服務端返回的資訊顯示到textview上。

客戶端

一、get請求:

第一步:建立請求,連線伺服器。

<span style="white-space:pre">			</span>String name = URLEncoder.encode("小紅", "utf-8");   //中文輸入先指定編碼,不然會出現亂碼
			//get請求帶引數的URL地址   http://192.168.1.112:8080/app/myweb?username=小紅&password=abcd  
			URL url = new URL(httpUrl+"?username="+name+"&password=abcd"); 
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");	//請求方式
			conn.setConnectTimeout(15000);  //設定連線超時
			conn.setReadTimeout(10000);  //設定讀取超時
			conn.connect();  //建立連線
這裡已經將引數加進去了。由於get請求的引數是直接加在URL地址之後,形式如同 http://192.168.1.112:8080/app/myweb?username=小紅&password=abcd    問號後面就是攜帶的引數,中文引數需要先指定編碼集,防止亂碼。若沒有引數則構造URL時就只需要協議地址。

第二步:伺服器請求連線成功後,伺服器接到引數,並作出響應,客戶端只需從連線中的流中讀出響應即可。

<span style="white-space:pre">			</span>InputStream in = conn.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));  //得到連線伺服器的緩衝流
			String line;
			StringBuilder sb = new StringBuilder();
			while((line=br.readLine()) != null){    //從服務中讀取請求返回的資料
				sb.append(line);
			}

最後看看get請求的完整Demo:
<span style="white-space:pre">	</span>/*get請求方式連線伺服器   get請求傳遞引數在url後面加引數*/
	public String getHttpDoget(String httpUrl){
		try {
			String name = URLEncoder.encode("小紅", "utf-8");   //中文輸入先指定編碼,不然會出現亂碼
			//get請求帶引數的URL地址   http://192.168.1.112:8080/app/myweb?username=小紅&password=abcd  
			URL url = new URL(httpUrl+"?username="+name+"&password=abcd"); 
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");	//請求方式
			conn.setConnectTimeout(15000);  //設定連線超時
			conn.setReadTimeout(10000);  //設定讀取超時
			conn.connect();  //建立連線
			
			InputStream in = conn.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));  //得到連線伺服器的緩衝流
			String line;
			StringBuilder sb = new StringBuilder();
			while((line=br.readLine()) != null){    //從服務中讀取請求返回的資料
				sb.append(line);
			}
			return sb.toString();
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

按鈕監聽中,由於請求伺服器連線是耗時操作,需要放到子執行緒中,這裡採用的是AsyncTask非同步操作實現,若需要學習AsyncTask非同步操作請參見:http://blog.csdn.net/tom_xiaoxie/article/details/49803413
<span style="white-space:pre">		</span>mConnecyBtn = (Button) findViewById(R.id.http_doget_btn);
		mConnecyBtn.setOnClickListener(new OnClickListener() {
			String httpUrl = "http://192.168.1.112:8080/app/myweb";
			@Override
			public void onClick(View v) {
				new AsyncTask<String, Void, String>(){
					@Override
					protected String doInBackground(String... params) {
						return getHttpDoget(params[0]);  //呼叫請求響應方法
					}
					protected void onPostExecute(String result) {
						mShowMsgTxt.setText(result);
					};
				}.execute(httpUrl);
			}
		});
二、doPost請求:程式碼實現Post請求伺服器響應跟get請求區別不大,只是Post請求在向伺服器傳參的時候,需要重新構造流來寫入引數。這是由於Get請求只有一個流,引數是直接附加在url後,而Post請求的引數是通過另外的流來傳遞的,不通過URL,所以可以很大。也可以傳遞二進位制資料。如檔案的上傳。Post建立連線及上傳引數Demo如下:
<span style="white-space:pre">			</span>URL url = new URL(httpUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");  //請求方法
			conn.setConnectTimeout(15000);  //設定連線超時
			conn.setReadTimeout(10000);  //設定讀取超時
			conn.connect();  //建立連線
			
			/*得到流向伺服器傳資料*/
			OutputStream out = conn.getOutputStream();
			PrintWriter pr = new PrintWriter(out);
			pr.print("username=小明&password=1234");
			pr.flush();

獲取伺服器響應的資料跟gen請求一樣。直接獲取輸入流來讀取資料即可。
<span style="white-space:pre">			</span>/*讀取服務端資料*/
			InputStream in = conn.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));  //得到連線伺服器的緩衝流
			String line;
			StringBuilder sb = new StringBuilder();
			while((line=br.readLine()) != null){    //從服務中讀取請求返回的資料
				sb.append(line);
			}

還是貼上整個方法的Demo和按鈕事件Demo:

post方式請求:

<span style="white-space:pre">	</span>/*post請求方式連線伺服器,給伺服器傳遞引數用流寫入的方式*/
	public String getHttpDopost(String httpUrl){
		try {
			URL url = new URL(httpUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");  //請求方法
			conn.setConnectTimeout(15000);  //設定連線超時
			conn.setReadTimeout(10000);  //設定讀取超時
			conn.connect();  //建立連線
			
			/*得到流向伺服器傳資料*/
			OutputStream out = conn.getOutputStream();
			PrintWriter pr = new PrintWriter(out);
			pr.print("username=小明&password=1234");
			pr.flush();
			
			/*讀取服務端資料*/
			InputStream in = conn.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));  //得到連線伺服器的緩衝流
			String line;
			StringBuilder sb = new StringBuilder();
			while((line=br.readLine()) != null){    //從服務中讀取請求返回的資料
				sb.append(line);
			}
			return sb.toString();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

按鈕監聽:
<span style="white-space:pre">		</span>mDopostBtn = (Button) findViewById(R.id.http_dopost_btn);
		mDopostBtn.setOnClickListener(new OnClickListener() {
			String http = "http://192.168.1.112:8080/app/myweb";
			@Override
			public void onClick(View v) {
				new AsyncTask<String, Void, String>(){
					@Override
					protected String doInBackground(String... params) {
						return getHttpDopost(params[0]);
					}
					protected void onPostExecute(String result) {
						mShowMsgTxt.setText(result);
					};
				}.execute(http);
			}
		});

服務端

最後看看服務端做了什麼?服務端就是將客服端傳來的引數獲取到並且返回給客服端。
package CatServelet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WebTestServelet extends HttpServlet {
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.setContentType("text/html;charset=utf-8");  //防止中文亂碼
		String name = req.getParameter("username");
		//name = new String(name.getBytes("ISO-8859-1"),"UTF-8");   //解決亂碼問題方式一
		System.out.println(name);
		String password = req.getParameter("password");
		resp.getWriter().print("password:" + password +"\n" +"username:"+name);
	}
	
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");//設定請求編碼
		resp.setContentType("text/html;charset=utf-8");  //設定響應編碼 防止中文亂碼
		String name = req.getParameter("username");
		String password = req.getParameter("password");
		System.out.println(name);
		resp.getWriter().print("password:" + password +"\n" +"username:"+name);
	}
}


亂碼問題:首先肯定是統一所有編譯器的編碼集如UTF-8.

解決doGet請求亂碼問題,這裡設定了兩處的編碼集,一是在客戶端請求服務端是傳入的引數先指定編碼集UTF-8。

String name = URLEncoder.encode("小紅", "utf-8");   //中文輸入先指定編碼,不然會出現亂碼

二是服務端響應時設定響應編碼集。
resp.setContentType("text/html;charset=utf-8");  //設定響應編碼集 防止中文亂碼

至於doPost請求的亂碼,只需要在服務端設定請求編碼和響應編碼就行了。
<span style="white-space:pre">		</span>req.setCharacterEncoding("UTF-8");//設定請求編碼
		resp.setContentType("text/html;charset=utf-8");  //設定響應編碼 防止中文亂碼

延生:

get請求和post請求的區別與比較:
Get請求只有一個流,引數附加在url後面,地址行顯示要傳送的資訊,大小個數有嚴格的限制且只能是字串。

Post請求的引數通過另外的流傳遞,不通過URL,所以可以很大,也可以傳遞二進位制資料如檔案。

就是引數傳遞方式,引數大小,引數型別有區別。

1、安全性:get請求引數顯示在url地址後面,可能存在安全性。如密碼,post請求可以解決這個問題。

2、伺服器接收方式  伺服器隨機接收get請求的資料,一旦斷電等意外原因,伺服器不會知道資訊是否傳送完畢。而post請求是伺服器先接收資料資訊長度,在接受資料。

3、form執行方式。當form框裡面的method為get時,執行doGet()方法。為post時,執行doPost()方法。

4、資訊容量限制  get請求的引數資訊有限制,post請求沒有限制。

get請求亂碼:

設定接受引數(客服端傳送來的引數)編碼集有兩種方式,一是更改伺服器配置檔案,開啟Tomcat--->conf目錄下的server.xml檔案

找到<Connector>標籤在裡面加一行URIEncoding="UTF-8"設定編碼集。

另一種方式是得到引數後轉碼

<span style="white-space:pre">		</span>String name = req.getParameter("username");
		name = new String(name.getBytes("ISO-8859-1"),"UTF-8");   //解決亂碼問題方式一
而響應請求(傳送給客戶端的引數)引數則用resp.setContentType("text/html;charset=utf-8");  //防止中文亂碼


post請求亂碼:

設定接受引數(客服端傳送來的引數)編碼集   req.setCharacterEncoding("UTF-8");//設定請求編碼

響應請求(傳送給客戶端的引數)引數  resp.setContentType("text/html;charset=utf-8");  //設定響應編碼 防止中文亂碼


特別注意在doget()中req.setCharacterEncoding("UTF-8")來設定接收引數編碼是沒有作用的。還是需要name = new String(name.getBytes("ISO-8859-1"),"UTF-8");   這種方式來轉碼。req.setCharacterEncoding("UTF-8")只在post()中有作用。

最後上圖並貼上完整程式碼:

activity程式碼:主佈局就只有兩個按鈕加一個textview控制元件。

package webview;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.sql.Connection;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.example.call.R;

public class HttpServeletActivity extends Activity {
	private TextView mShowMsgTxt;
	private Button mConnecyBtn,mDopostBtn;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.httpservelet_main_layout);
		mShowMsgTxt = (TextView) findViewById(R.id.http_text);
		
		mConnecyBtn = (Button) findViewById(R.id.http_doget_btn);
		mConnecyBtn.setOnClickListener(new OnClickListener() {
			String httpUrl = "http://192.168.1.112:8080/app/myweb";
			@Override
			public void onClick(View v) {
				new AsyncTask<String, Void, String>(){
					@Override
					protected String doInBackground(String... params) {
						return getHttpDoget(params[0]);
					}
					protected void onPostExecute(String result) {
						mShowMsgTxt.setText(result);
					};
				}.execute(httpUrl);
			}
		});
		
		mDopostBtn = (Button) findViewById(R.id.http_dopost_btn);
		mDopostBtn.setOnClickListener(new OnClickListener() {
			String http = "http://192.168.1.112:8080/app/myweb";
			@Override
			public void onClick(View v) {
				new AsyncTask<String, Void, String>(){
					@Override
					protected String doInBackground(String... params) {
						return getHttpDopost(params[0]);
					}
					protected void onPostExecute(String result) {
						mShowMsgTxt.setText(result);
					};
				}.execute(http);
			}
		});
	}
	
	/*post請求方式連線伺服器,給伺服器傳遞引數用流寫入的方式*/
	public String getHttpDopost(String httpUrl){
		try {
			URL url = new URL(httpUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");  //請求方法
			conn.setConnectTimeout(15000);  //設定連線超時
			conn.setReadTimeout(10000);  //設定讀取超時
			conn.connect();  //建立連線
			
			/*得到流向伺服器傳資料*/
			OutputStream out = conn.getOutputStream();
			PrintWriter pr = new PrintWriter(out);
			pr.print("username=小明&password=1234");
			pr.flush();
			
			/*讀取服務端資料*/
			InputStream in = conn.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));  //得到連線伺服器的緩衝流
			String line;
			StringBuilder sb = new StringBuilder();
			while((line=br.readLine()) != null){    //從服務中讀取請求返回的資料
				sb.append(line);
			}
			return sb.toString();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	/*get請求方式連線伺服器   get請求傳遞引數在url後面加引數*/
	public String getHttpDoget(String httpUrl){
		try {
			String name = URLEncoder.encode("小紅", "utf-8");   //中文輸入先指定編碼,不然會出現亂碼
			//get請求帶引數的URL地址   http://192.168.1.112:8080/app/myweb?username=小紅&password=abcd  
			URL url = new URL(httpUrl+"?username="+name+"&password=abcd"); 
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");	//請求方式
			conn.setConnectTimeout(15000);  //設定連線超時
			conn.setReadTimeout(10000);  //設定讀取超時
			conn.connect();  //建立連線
			
			InputStream in = conn.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));  //得到連線伺服器的緩衝流
			String line;
			StringBuilder sb = new StringBuilder();
			while((line=br.readLine()) != null){    //從服務中讀取請求返回的資料
				sb.append(line);
			}
			return sb.toString();
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}

服務端程式碼:
package CatServelet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WebTestServelet extends HttpServlet {
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.setContentType("text/html;charset=utf-8");  //防止中文亂碼
		String name = req.getParameter("username");
		//name = new String(name.getBytes("ISO-8859-1"),"UTF-8");   //解決亂碼問題方式一
		System.out.println(name);
		String password = req.getParameter("password");
		resp.getWriter().print("password:" + password +"\n" +"username:"+name);
	}
	
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");//設定請求編碼
		resp.setContentType("text/html;charset=utf-8");  //設定響應編碼 防止中文亂碼
		String name = req.getParameter("username");
		String password = req.getParameter("password");
		System.out.println(name);
		resp.getWriter().print("password:" + password +"\n" +"username:"+name);
	}
}