在Android開發中,網絡請求必然是必不可少。一般而言,都是基於http的網絡請求。有時候也會有SOCKET請求,這個後續的專題再講。今天,我們就先講講常用的Http請求。
http請求自然是遵循http協議的,相關內容請轉接:Java學習筆記之Http協議詳解
好了,開始今天的正題。
一、基礎HTTPURL請求方式
1、用get方式請求
URL url = new URL(
"http://192.168.31.144:10010/MINATest/servlet/DataTestServlet?username=victor&password=strikefreedom");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(TIME);
conn.setReadTimeout(TIME);
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
input = conn.getInputStream();
if (input != null) {
//拿到流後處理
}
}
2、用post方式請求
String data = "username=justice&password=infiniteJustice";
URL url = new URL(
"http://192.168.31.144:10010/MINATest/servlet/DataTestServlet");
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(TIME);
conn.setReadTimeout(TIME);
conn.setDoInput(true);// 允許輸入
conn.setDoOutput(true);// 允許輸出
conn.setUseCaches(false);// 不使用Cache
conn.setRequestProperty("Charset", ENCODING);
conn.setRequestProperty("Content-Length",
String.valueOf(data.length()));
conn.setRequestProperty("Content-Type", "text/*;charset=utf-8");
conn.setRequestMethod("POST");
DataOutputStream outStream = new DataOutputStream(
conn.getOutputStream());
outStream.write(data.getBytes());
outStream.flush();
outStream.close();
if (conn == null) {
return;
}
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
input = conn.getInputStream();
if (input != null) {
}
}
我們可以看到用post方式請求和用get方式傳入參數有點不同。
二、http訪問類的封裝
1、封裝邏輯
2、http訪問管理者
package com.example.nettest;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
/**
* @ClassName: FreedomHttpUrlUtils
* @author victor_freedom ([email protected])
* @createddate 2015-1-22 下午1:43:58
* @Description: http請求管理者
*/
public class FreedomHttpUrlUtils implements Runnable {
private Context context;
/** http訪問結果監聽器 */
private FreedomHttpListener listener;
/** 當前訪問線程 */
private Thread currentRequest = null;
/** 訪問鏈接 */
HttpURLConnection conn = null;
/** 拿到的流 */
InputStream input = null;
private static final String ENCODING = "UTF-8";
public static final int GET_MOTHOD = 1;
private static final int TIME = 40 * 1000;
public static final int POST_MOTHOD = 2;
/**
* 1: get請求 2: post請求
*/
private int requestStatus = 1;
/**
* <p>
* Title:
* </p>
* <p>
* Description:構造方法,其實在這裏可以傳入一個傳輸協議包,博主是測試代碼,所以請求中直接寫死了。
* </p>
*
* @param mContext
* @param listener
* 監聽器
* @param mRequeststatus
* 請求方式
*/
public FreedomHttpUrlUtils(Context mContext, FreedomHttpListener listener,
int mRequeststatus) {
this.context = mContext;
this.requestStatus = mRequeststatus;
this.listener = listener;
}
/**
* @Title: postRequest
* @Description:Post請求觸發
* @throws
*/
public void postRequest() {
requestStatus = 2;
currentRequest = new Thread(this);
currentRequest.start();
}
/**
* @Title: getRequeest
* @Description:GET請求觸發
* @throws
*/
public void getRequeest() {
requestStatus = 1;
currentRequest = new Thread(this);
currentRequest.start();
}
/**
* 對請求的字符串進行編碼
*
* @return
* @throws UnsupportedEncodingException
*/
public static String requestEncodeStr(String requestStr)
throws UnsupportedEncodingException {
return URLEncoder.encode(requestStr, ENCODING);
}
/**
* @Title: sendGetRequest
* @Description: 發送get請求
* @throws
*/
private void sendGetRequest() {
try {
URL url = new URL(
"http://192.168.31.144:10010/MINATest/servlet/DataTestServlet?username=victor&password=strikefreedom");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(TIME);
conn.setReadTimeout(TIME);
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
input = conn.getInputStream();
if (input != null) {
listener.action(FreedomHttpListener.EVENT_GET_DATA_SUCCESS,
readStream(input));
}
} else {
listener.action(FreedomHttpListener.EVENT_NETWORD_EEEOR, null);
}
} catch (SocketException e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_CLOSE_SOCKET, null);
} catch (SocketTimeoutException e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_NETWORD_EEEOR, null);
} catch (IOException e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_GET_DATA_EEEOR, null);
} catch (Exception e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_NETWORD_EEEOR, null);
}
}
/**
* @Title: sendPostRequest
* @Description: 發送post請求
* @throws
*/
private void sendPostRequest() {
try {
String data = "username=justice&password=infiniteJustice";
URL url = new URL(
"http://192.168.31.144:10010/MINATest/servlet/DataTestServlet");
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(TIME);
conn.setReadTimeout(TIME);
conn.setDoInput(true);// 允許輸入
conn.setDoOutput(true);// 允許輸出
conn.setUseCaches(false);// 不使用Cache
conn.setRequestProperty("Charset", ENCODING);
conn.setRequestProperty("Content-Length",
String.valueOf(data.length()));
conn.setRequestProperty("Content-Type", "text/*;charset=utf-8");
conn.setRequestMethod("POST");
DataOutputStream outStream = new DataOutputStream(
conn.getOutputStream());
outStream.write(data.getBytes());
outStream.flush();
outStream.close();
if (conn == null) {
return;
}
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
input = conn.getInputStream();
if (input != null) {
listener.action(FreedomHttpListener.EVENT_GET_DATA_SUCCESS,
readStream(input));
}
} else if (responseCode == 404) {
input = conn.getErrorStream();
if (input != null) {
listener.action(FreedomHttpListener.EVENT_GET_DATA_SUCCESS,
readStream(input));
} else {
listener.action(FreedomHttpListener.EVENT_NETWORD_EEEOR,
null);
}
} else {
listener.action(FreedomHttpListener.EVENT_NETWORD_EEEOR, null);
}
} catch (SocketException e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_CLOSE_SOCKET, null);
} catch (SocketTimeoutException e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_NETWORD_EEEOR, null);
} catch (IOException e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_GET_DATA_EEEOR, null);
} catch (Exception e) {
e.printStackTrace();
listener.action(FreedomHttpListener.EVENT_NETWORD_EEEOR, null);
}
}
/**
* @Title: isRunning
* @Description: 判斷是否正在訪問
* @return
* @throws
*/
public boolean isRunning() {
if (currentRequest != null && currentRequest.isAlive()) {
return true;
}
return false;
}
/**
* 讀取數據
*
* @param inStream
* 輸入流
* @return
* @throws Exception
*/
private Object readStream(InputStream inStream) throws Exception {
String result;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
result = new String(outStream.toByteArray(), ENCODING);
outStream.close();
inStream.close();
return result;
}
/**
* 取消當前HTTP連接處理
*/
public void cancelHttpRequest() {
if (currentRequest != null && currentRequest.isAlive()) {
if (input != null) {
try {
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}
input = null;
if (conn != null) {
try {
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
conn = null;
currentRequest = null;
System.gc();
}
}
/**
* 發送請求
*/
public void run() {
// 判斷是否有網絡
boolean netType = NetUtils.checkNetWork(context);
if (netType) {
if (requestStatus == 1) {
sendGetRequest();
} else if (requestStatus == 2) {
sendPostRequest();
}
} else {
listener.action(FreedomHttpListener.EVENT_NOT_NETWORD, null);
}
}
}
我們可以看到,當訪問有結果以後,會出發監聽器的action方法,那麼我們再來看看監聽器的定義
3、http訪問結果監聽器
package com.example.nettest;
/**
* @ClassName: FreedomHttpListener
* @author victor_freedom ([email protected])
* @createddate 2015-1-24 下午4:28:31
* @Description: 監聽器
*/
public interface FreedomHttpListener {
public static final int EVENT_BASE = 0x100;
/**
* 沒有網絡的信息提示
* */
public static final int EVENT_NOT_NETWORD = EVENT_BASE + 1;
/**
* 網絡異常的信息提示
* */
public static final int EVENT_NETWORD_EEEOR = EVENT_BASE + 2;
/**
* 獲取網絡數據失敗
* */
public static final int EVENT_GET_DATA_EEEOR = EVENT_BASE + 3;
/**
* 獲取網絡數據成功
* */
public static final int EVENT_GET_DATA_SUCCESS = EVENT_BASE + 4;
/**
* 獲取網絡數據成功
* */
public static final int EVENT_CLOSE_SOCKET = EVENT_BASE + 5;
public void action(int actionCode, Object object);
}
我們可以看到,在觸發action動作的時候,我們會傳入一個code和一個對象,這個code表示當前訪問是否成功,而對象就是要傳輸的訪問結果。
4、消息處理器
/**
* @ClassName: BaseHandler
* @author victor_freedom ([email protected])
* @createddate 2015-1-24 下午4:32:05
* @Description: 消息處理器
*/
class BaseHandler extends Handler {
private Context context;
/** 事件回調接口處理 */
private FreedomDataCallBack callBack;
public BaseHandler(Context context, FreedomDataCallBack callBack) {
this.context = context;
this.callBack = callBack;
}
public void handleMessage(Message msg) {
// 根據不同的結果觸發不同的動作
if (msg.what == FreedomHttpListener.EVENT_GET_DATA_SUCCESS) {
if (msg.obj == null) {
callBack.onFailed();
} else {
// 後臺處理數據
callBack.processData(msg.obj, true);
}
} else if (msg.what == FreedomHttpListener.EVENT_NOT_NETWORD) {
callBack.onFailed();
// CommonUtil.showInfoDialog(context,
// getString(R.string.net_error));
} else if (msg.what == FreedomHttpListener.EVENT_NETWORD_EEEOR) {
callBack.onFailed();
} else if (msg.what == FreedomHttpListener.EVENT_GET_DATA_EEEOR) {
callBack.onFailed();
} else if (msg.what == FreedomHttpListener.EVENT_CLOSE_SOCKET) {
}
callBack.onFinish();
}
}
我們可以看到,在消息處理器中傳入了一個回調接口類,在不同的返回結果中,觸發不同的回調動作。
5、回調接口
package com.example.nettest;
/**
* @ClassName: FreedomDataCallBack
* @author victor_freedom ([email protected])
* @createddate 2015-1-24 下午4:33:38
* @Description: 回調接口,處理返回數據
* @param <T>
*/
public interface FreedomDataCallBack<T> {
public abstract void onStart();
public abstract void processData(T paramObject, boolean paramBoolean);
public abstract void onFinish();
public abstract void onFailed();
}
因爲我們不知道返回的結果是什麼類型的,這裏採用泛型來處理
三、http封裝後的使用
1、從服務器拿數據的方法
/**
* @Title: getDataFromServer
* @Description: 從服務器拿數據
* @param requestType
* 請求方式
* @param callBack
* 回調接口
* @throws
*/
protected void getDataFromServer(int requestType,
FreedomDataCallBack callBack) {
final BaseHandler handler = new BaseHandler(this, callBack);
freedomHttpUrlUtils = new FreedomHttpUrlUtils(mContext,
new FreedomHttpListener() {
@Override
public void action(int actionCode, Object object) {
Message msg = new Message();
switch (actionCode) {
case FreedomHttpListener.EVENT_NOT_NETWORD:
msg.what = FreedomHttpListener.EVENT_NOT_NETWORD;
break;
case FreedomHttpListener.EVENT_NETWORD_EEEOR:
msg.what = FreedomHttpListener.EVENT_NETWORD_EEEOR;
break;
case FreedomHttpListener.EVENT_CLOSE_SOCKET:
msg.what = FreedomHttpListener.EVENT_CLOSE_SOCKET;
break;
case FreedomHttpListener.EVENT_GET_DATA_EEEOR:
msg.what = FreedomHttpListener.EVENT_GET_DATA_EEEOR;
msg.obj = null;
break;
case FreedomHttpListener.EVENT_GET_DATA_SUCCESS:
msg.obj = object;
msg.what = FreedomHttpListener.EVENT_GET_DATA_SUCCESS;
break;
default:
break;
}
handler.sendMessage(msg);
}
}, requestType);
callBack.onStart();
// 選擇不同的請求方法
if (requestType == FreedomHttpUrlUtils.GET_MOTHOD) {
freedomHttpUrlUtils.getRequeest();
} else if (requestType == FreedomHttpUrlUtils.POST_MOTHOD) {
freedomHttpUrlUtils.postRequest();
}
}
2、方法的使用
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String parameter = request.getParameter("username");
String parameter2 = request.getParameter("password");
System.out.println(parameter + parameter2);
response.setContentType("text/*;charset=utf-8");
response.getWriter().write(parameter + "-" + parameter2);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// doGet(request, response);
System.out.println("post");
ServletInputStream inputStream = request.getInputStream();
ByteOutputStream b = new ByteOutputStream();
int len = -1;
byte[] buf = new byte[1024];
while ((len = inputStream.read(buf)) != -1) {
b.write(buf, 0, buf.length);
}
String s = b.toString();
String[] split = s.split("&");
System.out.println(split[0] + split[1]);
response.setContentType("text/*;charset=utf-8");
response.getWriter().write(
split[0].substring(split[0].lastIndexOf("=") + 1) + "-"
+ split[1].substring(split[1].lastIndexOf("=") + 1));
}
/**
* @ClassName: MainActivity
* @author victor_freedom ([email protected])
* @createddate 2015-1-24 下午4:40:59
* @Description: TODO
*/
public class MainActivity extends BaseActivity {
private TextView get;
private TextView post;
@Override
protected void findViewById() {
get = (TextView) findViewById(R.id.hello);
post = (TextView) findViewById(R.id.post);
}
@Override
protected void loadViewLayout() {
setContentView(R.layout.activity_main);
}
@Override
protected void processLogic() {
}
@Override
protected void setListener() {
}
@Override
protected void init() {
getDataFromServer(1, new FreedomDataCallBack<String>() {
@Override
public void onStart() {
}
@Override
public void processData(String paramObject, boolean paramBoolean) {
get.setText(paramObject);
}
@Override
public void onFinish() {
}
@Override
public void onFailed() {
}
});
getDataFromServer(2, new FreedomDataCallBack<String>() {
@Override
public void onStart() {
}
@Override
public void processData(String paramObject, boolean paramBoolean) {
post.setText(paramObject);
}
@Override
public void onFinish() {
}
@Override
public void onFailed() {
}
});
}
我們這裏分別採用了兩種方法訪問,傳入參數也是不同的,我們看訪問結果,兩個textView均顯示了訪問返回的值。