使用 HTTP 協議訪問網路的兩種方式:HttpURLConnection 和 HttpClient
阿新 • • 發佈:2019-01-29
安卓中進行基於HTTP協議的網路訪問
說明: HttpClient (apache開發)
HttpURLConnection(google在釋出安卓時在Java基礎上修改得到的)
使用HC(HttpClient)/UC(HttpURLConnection)進行網路訪問的基本步驟:
0.申請許可權 INTERNET訪問許可權
1. 任何網路訪問的相關程式碼,必須在工作執行緒中執行!
2. 建立HC/UC物件
3. 聲明發起網路訪問的方式(GET/POST)
4. 進行網路連線
5. 獲得伺服器響應的結果
6. 解析結果,提取需要的內容
7. 解析結果要提交到UI執行緒進行呈現
- 利用POST方式發起請求,引數要放到請求實體中,並且在請求頭中新增對實體中引數的說明。例如:
新增引數:
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("loginname", user.getName()));
parameters.add(new BasicNameValuePair("password", user.getPassword()));
parameters.add(new BasicNameValuePair("realname" , user.getRealname()));
parameters.add(new BasicNameValuePair("email", user.getEmail()));
HttpEntity entity = new UrlEncodedFormEntity(parameters);
post.setEntity(entity);
新增說明:
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
- 在HttpClient中設定頭: post.setHeader(key,value);
- 在HttpURLConnection中設定頭:
connection.setReqeustProperty(key ,value);
建一個小專案進行說明
1. activity_main.xml 佈局檔案
<LinearLayout 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:orientation="vertical"
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="com.example.ui.MainActivity" >
<EditText
android:id="@+id/et_main_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入使用者名稱..."
android:textSize="16sp" />
<EditText
android:id="@+id/et_main_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:hint="請輸入密碼..."
android:inputType="textPassword"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<EditText
android:id="@+id/et_main_vertifycode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="3"
android:hint="請輸入驗證碼..."
android:textSize="16sp" />
<ImageView
android:id="@+id/iv_main_vertifycode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/ic_launcher" />
</LinearLayout>
<View
android:layout_width="1dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="regist"
android:text="註冊"
android:textSize="16sp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="login"
android:text="登入"
android:textSize="16sp" />
</LinearLayout>
效果圖:
2. 建一個MainActivity 類
package com.example.ui;
import com.example.biz.EmsBiz;
import com.example.listener.OnLoginFinishListener;
import com.example.listener.OnRefreshVertifyCodeListener;
import com.example.web.R;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText etName,etPwd,etCode;
EmsBiz biz;
ImageView ivImageView;
String sid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
biz=new EmsBiz(this);
initView();//初始化介面
}
private void initView() {
ivImageView=(ImageView) findViewById(R.id.iv_main_vertifycode);
//驗證碼的監聽器
ivImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
refresh();//每點選一次驗證碼,就重新整理一次
}
});
etName = (EditText) findViewById(R.id.et_main_name);
etPwd = (EditText) findViewById(R.id.et_main_password);
etCode = (EditText) findViewById(R.id.et_main_vertifycode);
}
@Override
protected void onResume() {
super.onResume();
//驗證碼的重新整理
refresh();
}
protected void refresh() {
//為refresh()設定回撥的getVertify方法
//介面OnRefreshVertifyCodeListener(),並實現介面方法onRefreshFinished
biz.getVertify(new OnRefreshVertifyCodeListener() {
@Override
public void onRefreshFinished(Bitmap bitmap, String sessionId) {
if(bitmap!=null){
ivImageView.setImageBitmap(bitmap);
}
}
});
}
//“註冊”按鈕的onClick,跳轉到“註冊介面”
public void regist(View v) {
Intent intent=new Intent(this,RegistActivity.class);
startActivity(intent);
}
//“登入”按鈕的onClick
public void login(View v) {
//應該加入判空
String loginname = etName.getText().toString();
String password = etPwd.getText().toString();
String code = etCode.getText().toString();
//與上面refresh()一樣,添加回調監聽
biz.login(loginname,password,code,sid,new OnLoginFinishListener() {
@Override
public void OnLoginFinish(String result) {
if(result!=null){
if(result.contains("ok")){
//加入Toast提示
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
refresh();
//如果輸入不正確,將驗證碼和密碼清空
etPwd.setText("");
etCode.setText("");
}
}else{
Toast.makeText(MainActivity.this, "伺服器錯誤", Toast.LENGTH_SHORT).show();
}
}
});
}
}
3. 建一個OnLoginFinishListener 介面
package com.example.listener;
public interface OnLoginFinishListener {
void OnLoginFinish(String result);
}
4. 建一個EmsBiz 類
這個類屬於管理層介面了,對於自己做小專案沒有太大意義
package com.example.biz;
import com.example.Utli.EmsUtli;
import com.example.bean.Emp;
import com.example.bean.User;
import com.example.listener.OnAddEmpFinishListener;
import com.example.listener.OnLoginFinishListener;
import com.example.listener.OnRefreshVertifyCodeListener;
import com.example.listener.onRegistFinishListener;
import android.content.Context;
import android.util.Log;
public class EmsBiz {
private Context context;
public EmsBiz(Context context) {
this.context = context;
}
//這裡使用兩種方式:HttpClient和HttpURLConnection
public void login(String loginname,String password,
String code,String sid,OnLoginFinishListener listener) {
//EmsUtli.login(loginname,password,code,sid,listener);
EmsUtli.login2(loginname,password,code,sid,listener);
}
}
5. 最後再建一個EmsUtli類
package com.example.Utli;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.util.EntityUtils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import com.example.bean.Emp;
import com.example.bean.User;
import com.example.bean.ValueObject;
import com.example.listener.OnAddEmpFinishListener;
import com.example.listener.OnLoginFinishListener;
import com.example.listener.OnRefreshVertifyCodeListener;
import com.example.listener.onRegistFinishListener;
public class EmsUtli {
//使用HttpClient方式
public static void login(final String loginname, final String password, final String code,final String sid, final OnLoginFinishListener listener) {
new AsyncTask<Void, Void, String>(){
@Override
protected String doInBackground(Void... params) {
try {
//HttpClient 是一個介面,因此無法建立它的例項,通常情況下都會建立一個DefaultHttpClient 的例項
HttpClient client= new DefaultHttpClient();
HttpPost post=new HttpPost("http://172.88.134.136:8080/ems/login.do");
//新增一個請求頭,對請求實體中的引數做一個說明
//在HttpClient中設定頭:post.setHeader(key,value);
post.setHeader("Cookie",sid);
post.setHeader("Content-Type","application/x-www-form-urlencoded");
//在post中新增請求引數
//請求引數會新增在請求實體中
List<NameValuePair>parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("loginname", loginname));
parameters.add(new BasicNameValuePair("password", password));
parameters.add(new BasicNameValuePair("code", code));
HttpEntity entity=new UrlEncodedFormEntity(parameters);
post.setEntity(entity);
HttpResponse resp=client.execute(post);
String result=EntityUtils.toString(resp.getEntity());
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result) {
listener.OnLoginFinish(result);
};
}.execute();
}
//HttpURLConnection進行註冊
public static void login2(final String loginname, final String password, final String code,
final String sid, final OnLoginFinishListener listener) {
new Thread(){
public void run() {
try {
URL url=new URL("http://172.88.134.136:8080/ems/login.do");
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);//接收伺服器響應的內容
connection.setDoOutput(true);//要向伺服器提交內容
//在請求頭中,為請求實體中的內容做說明
//在HttpURLConnection中設定頭:connection.setReqeustProperty(key ,value);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Cookie", sid);
connection.connect();
OutputStream out=connection.getOutputStream();
PrintWriter pw=new PrintWriter(out,true);
pw.write(getParams(loginname,password,code));
pw.close();
//從客戶端獲取伺服器的響應的內容
InputStream in=connection.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(in));
//在這裡我們只有一行,所以這樣寫
//若為多行資料,需用:
/*StringBuilder sb=new StringBuilder();
while ((line=br.readLine())!=null) {
sb.append(line);
}*/
final String result=br.readLine();
br.close();
//在主執行緒執行
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
listener.OnLoginFinish(result);
}
});
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
//獲得引數的方法
protected static String getParams(String loginname, String password,
String code) {
Map<String, String> map=new HashMap<String,String>();
map.put("loginname", loginname);
map.put("password", password);
map.put("code", code);
StringBuilder sb=new StringBuilder();
for(Entry<String, String> entity:map.entrySet()){
sb.append(entity.getKey()).append("=").
append(entity.getValue()).append("&");
}
//-1是為了減去最後的“&”字元
return sb.substring(0, sb.length()-1);
}
別忘了在AndroidManifest.xml中註冊
<uses-permission android:name="android.permission.INTERNET" />
在這裡我們選擇了HttpURLConnection執行,將HttpClient進行了註釋,比較推薦使用HttpURLConnection進行HTTP協議訪問網路