Android連線Tomcat伺服器
在保證伺服器是正常狀態時,將從Android模擬器上傳送請求給服務端並接收服務端返回來的響應。
保證HttpServlet配置正常。可以通過在瀏覽器輸入配置的地址,若能正常響應,那麼在Android中去請求的話也是能正常響應的。
這裡列舉的Demo是在activity中有兩個按鈕,分別執行get請求和post請求的同時傳遞引數到服務端,並將服務端返回的資訊顯示到textview上。
客戶端
一、get請求:
第一步:建立請求,連線伺服器。
這裡已經將引數加進去了。由於get請求的引數是直接加在URL地址之後,形式如同 http://192.168.1.112:8080/app/myweb?username=小紅&password=abcd 問號後面就是攜帶的引數,中文引數需要先指定編碼集,防止亂碼。若沒有引數則構造URL時就只需要協議地址。<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(); //建立連線
第二步:伺服器請求連線成功後,伺服器接到引數,並作出響應,客戶端只需從連線中的流中讀出響應即可。
<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);
}
}