之前我們探討了Tomcat 搭建 HTTP 服務器,這節我們探討一下Android 與 服務器的通信。
Android HTTP請求可以通過以下兩種方式實現:
1. 使用JDK中HttpURLConnection訪問網絡資源(POST, GET)
2.使用Apache的HttpClient訪問網絡資源(POST,
GET)
今天主要探討第一種:
S0 安卓環境搭建
S1 新建一個安卓工程
用 MyEclipse (或 Eclipse) 新建一個安卓程序並命名爲 AndroidHTTPDemo。
創建好空工程,點擊運行,結果如截圖所示:( HelloWorld 程序 )
S2 簡單設計安卓界面,在原來基礎上增加一個Button即可。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/Infotv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/ShowBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginTop="82dp"
android:text="Show" />
</RelativeLayout>
SS1 GET 方法
S3 新建一個WebService類,在com.rxz.web包下,編寫安卓的通信程序:
package com.rxz.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class WebService {
// IP地址
private static String IP = "10.0.2.2:8080";
/**
* 通過Get方式獲取HTTP服務器數據
* @return
*/
public static String executeHttpGet() {
HttpURLConnection conn = null;
InputStream is = null;
try {
// URL 地址
String path = "http://" + IP + "/HelloWeb/servlet/MyServlet";
conn = (HttpURLConnection) new URL(path).openConnection();
conn.setConnectTimeout(5000); // 設置超時時間
conn.setRequestMethod("GET"); // 設置獲取信息方式
conn.setRequestProperty("Charset", "UTF-8"); // 設置接收數據編碼格式
if(conn.getResponseCode() == 200){
is = conn.getInputStream();
return parseInfo(is);
}
return null;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 意外退出時進行連接關閉保護
if (conn != null) {
conn.disconnect();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 將輸入流轉化爲 String 型
* @param inStream
* @return
* @throws Exception
*/
private static String parseInfo(InputStream inStream) throws Exception{
byte[] data = read(inStream);
//轉化爲字符串
return new String(data, "UTF-8");
}
/**
* 將輸入流轉化爲byte型
* @param inStream
* @return
* @throws Exception
*/
public static byte[] read(InputStream inStream) throws Exception{
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = inStream.read(buffer)) != -1){
outputStream.write(buffer,0,len);
}
inStream.close();
return outputStream.toByteArray();
}
}
S4 修改MainActivity界面類,獲取Button,並響應按鈕點擊事件:
package com.rxz.androidhttpdemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import com.rxz.web.WebService;
public class MainActivity extends Activity implements OnClickListener {
// 顯示按鈕
private Button showbtn = null;
// 顯示文本區域
private TextView infotv = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 獲取控件
showbtn = (Button) findViewById(R.id.ShowBtn);
infotv = (TextView) findViewById(R.id.Infotv);
// 設置按鈕監聽器
showbtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
// 顯示按鈕點擊事件
case R.id.ShowBtn:
String info = WebService.executeHttpGet();
infotv.setText(info);
break;
}
}
}
S5 切記:增加安卓聯網權限!!!在AndroidManifest.xml文件裏面:
<!-- 聯網權限 -->
<uses-permission android:name="android.permission.INTERNET" />
S6 先運行01節博客所講的HTTP 服務器,然後運行安卓程序,按下按鈕,效果如下,表明成功。
SS2 POST方法
S7 新建一個WebServicePost類,在com.rxz.web包下,編寫安卓的通信程序:
package com.rxz.web;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
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 WebServicePost {
// IP地址
private static String IP = "10.0.2.2:8080";
/**
* 通過 POST 方式獲取HTTP服務器數據
* @param infor
* @param credit
* @return
* @throws Exception
*/
public static String executeHttpPost(String infor,String credit){
try {
String path = "http://" + IP + "/HelloWeb/servlet/MyServlet";
// 發送指令和信息
Map<String,String> params = new HashMap<String,String>();
params.put("infor", infor);
params.put("state", credit);
return sendPOSTRequest(path, params, "UTF-8");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 處理髮送數據請求
* @param path
* @param params
* @param encoding
* @return
* @throws Exception
*/
private static String sendPOSTRequest(String path,
Map<String, String> params, String encoding) throws Exception {
// TODO Auto-generated method stub
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
if(params != null && !params.isEmpty()){
for(Map.Entry<String, String> entry : params.entrySet()){
pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
}
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs,encoding);
HttpPost post = new HttpPost(path);
post.setEntity(entity);
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(post);
// 判斷是否成功收取信息
if(response.getStatusLine().getStatusCode() == 200){
return getInfo(response);
}
// 未成功收取信息,返回空指針
return null;
}
/**
* 收取數據
* @param response
* @return
* @throws Exception
*/
private static String getInfo(HttpResponse response) throws Exception{
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
//將輸入流轉化爲byte型
byte[] data = WebService.read(is);
//轉化爲字符串
return new String(data, "UTF-8");
}
}
S8 修改MainActivity界面類,獲取Button,並響應按鈕點擊事件:
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
// 顯示按鈕點擊事件
case R.id.ShowBtn:
//String info = WebService.executeHttpGet();
//infotv.setText(info);
String info = WebServicePost.executeHttpPost("MyCommand", "This is My Info");
infotv.setText(info);
break;
}
}
S9 修改服務器MyServlet類的doPost方法,實現獲取用戶傳遞信息並反饋信息的功能:
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("************ POST正在接收請求 *************");
// 設置編碼方式
request.setCharacterEncoding("UTF-8");
// 獲取到 命令信息
String infor = request.getParameter("infor");
// 獲取到 參數信息
String credit = request.getParameter("state");
System.out.println("收到的客戶端的信息爲:" + infor);
System.out.println(" 收到客戶端的命令:" + credit);
System.out.println("************ 正在發送信息 *************");
// 發送信息
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("回饋信息" + infor + ":" + credit);
out.flush();
out.close();
}
S10 重新運行HTTP 服務器,然後運行安卓程序,按下按鈕,效果如下,表明成功。
附上源碼: