HTTP通信
接上篇。项目主要使用HTTP协议与设备通信,所以最先说说。
代码
先上代码,又臭又长。后面有说明。
HttpConnection.java
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
/**
* Created by song on 2017/5/28.
*/
/**
* HTTP通信类
* if in Chinese
* URLEncoder.encode("xxxx","utf-8");
* URLDecoder.decode("xxxx","utf-8");
*/
public class HttpConnection extends Thread {
private boolean mRunning = true;
private boolean mConnected = false;
private HttpConnection() {
}
// 单实例
private static final Object mSyncObject = new Object();
private static HttpConnection mInstance;
public static HttpConnection getInstance() {
synchronized (mSyncObject) {
if (mInstance != null) {
return mInstance;
}
mInstance = new HttpConnection();
}
return mInstance;
}
// 传递数据给界面
private Handler mHandler = null;
public void setHandler(Handler handler) {
this.mHandler = handler;
}
// Cookie
private String mCookie = "";
public String getCookie() {
return mCookie;
}
// 请求队列
private Queue<Request> queueRequest = new LinkedList<>();
public void Add(int type, int id) {
Add(type, id, "");
}
public void Add(int type, int id, String addition) {
Add(type, id, addition, "");
}
public void Add(int type, int id, String addition, String data) {
Request request = new Request(type, id, Defines.URLS[id] + addition, data);
queueRequest.offer(request);
}
// GET请求
private Response executeHttpGet(URL url) {
if (url == null) {
return null;
}
int responseCode = 0;
String header = "";
String result = "";
HttpURLConnection connection = null;
try {
// 发送HTTP GET请求
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET"); // 设置请求的方式
connection.setReadTimeout(5000); // 设置超时的时间
connection.setConnectTimeout(5000); // 设置链接超时的时间
if (!mCookie.equals("")) {
connection.setRequestProperty("Cookie", mCookie);
}
connection.connect();
// 接收HTTP GET响应
Map<String, List<String>> responseHeaderMap = connection.getHeaderFields();
int size = responseHeaderMap.size();
Map<String, Object> headerMap = new HashMap<>();
for (int i = 0; i < size; i++) {
String responseHeaderKey = connection.getHeaderFieldKey(i);
String responseHeaderValue = connection.getHeaderField(i);
if (responseHeaderKey != null && responseHeaderValue != null) {
headerMap.put(responseHeaderKey, responseHeaderValue);
}
}
header = JSONGenerator.GenJSON(headerMap).toString();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
String strCookie = connection.getHeaderField("Set-Cookie");
if (strCookie != null) {
mCookie = strCookie;
mConnected = true;
}
InputStream inputStream = connection.getInputStream();
int len;
byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) > 0) {
result += new String(bytes, 0, len, "ISO-8859-1");
}
inputStream.close();
// in = new InputStreamReader(connection.getInputStream());
// BufferedReader bufferedReader = new BufferedReader(in);
// int len = 0;
// char [] buffer = new char[1024];
// while((len = bufferedReader.read(buffer)) > 0){
// result += new String(buffer, 0, len);
// }
// StringBuffer strBuffer = new StringBuffer();
// String line;
// while ((line = bufferedReader.readLine()) != null) {
// strBuffer.append(line);
// }
// result = strBuffer.toString();
} else if (responseCode == HttpURLConnection.HTTP_ACCEPTED
|| responseCode == HttpURLConnection.HTTP_PARTIAL) {
InputStream inputStream = connection.getInputStream();
int len;
byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) > 0) {
result += new String(bytes, 0, len, "ISO-8859-1");
}
inputStream.close();
} else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
result = "error";
mConnected = false;
} else {
result = String.valueOf(responseCode);
}
} catch (Exception e) {
result = "error";
mConnected = false;
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
return new Response(responseCode, header, result);
}
// POST请求
private Response executeHttpPost(URL url, String body) {
if (url == null) {
return null;
}
int responseCode = 0;
String header = "";
String result = null;
HttpURLConnection connection = null;
InputStreamReader in = null;
try {
// 发送HTTP POST请求
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Cookie", mCookie);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Charset", "utf-8");
if (!body.equals("")) {
DataOutputStream dop = new DataOutputStream(connection.getOutputStream());
dop.writeBytes(body);
dop.flush();
dop.close();
}
connection.connect();
// 接收HTTP POST响应
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
in = new InputStreamReader(connection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(in);
StringBuffer strBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
strBuffer.append(line);
}
result = strBuffer.toString();
} else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
result = "error";
mConnected = false;
}
} catch (Exception e) {
result = "error";
mConnected = false;
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return new Response(responseCode, header, result);
}
// DELETE请求
private Response executeHttpDelete(URL url) {
if (url == null) {
return null;
}
int responseCode = 0;
String header = "";
String result = null;
HttpURLConnection connection = null;
try {
// 发送HTTP DELETE请求
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("DELETE");
connection.setRequestProperty("Cookie", mCookie);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Charset", "utf-8");
connection.connect();
// 接收HTTP DELETE响应
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
result = "success";
} else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
result = "error";
mConnected = false;
}
} catch (Exception e) {
result = "error";
mConnected = false;
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
return new Response(responseCode, header, result);
}
// 发送心跳和处理请求线程
@Override
public void run() {
mCookie = "";
mRunning = true;
while (mRunning) {
try {
Request request;
Response response = null;
int interfaceID = -1;
if (mConnected) {
interfaceID = Defines.INTERFACE_HEART;
URL url = new URL(Defines.URLS[interfaceID]);
response = executeHttpGet(url);
}
if ((request = queueRequest.poll()) != null) {
interfaceID = request.id;
URL url = new URL(request.toString());
if (mConnected) {
switch (request.type) {
case Defines.REQUEST_GET:
response = executeHttpGet(url);
break;
case Defines.REQUEST_POST:
response = executeHttpPost(url, request.data);
break;
case Defines.REQUEST_DELETE:
response = executeHttpDelete(url);
break;
default:
break;
}
} else if (request.id == Defines.INTERFACE_CONNECT) {
response = executeHttpGet(url);
}
sleep(1);
} else if (mConnected) {
sleep(500);
} else {
sleep(1000);
continue;
}
if (response != null) {
// 从消息池中取出一个message
Message msg = mHandler.obtainMessage();
if (response.toString().equals("error")) {
interfaceID = Defines.ERROR;
}
msg.what = interfaceID;
// Bundle是message中的数据
Bundle b = new Bundle();
b.putInt("Status", response.statusCode);
b.putString("Header", response.header);
b.putString("Body", response.data);
msg.setData(b);
// 传递数据
if (mHandler != null) {
mHandler.sendMessage(msg); // 向Handler发送消息,更新UI
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void close() {
mRunning = false;
}
// HTTP Request
private static class Request {
public final int type; // 请求的类型
public final int id; // 请求的ID
public final String content; // 请求的url
public final String data; // 请求的Body
public Request(int type, int id, String content, String data) {
this.type = type;
this.id = id;
this.content = content;
this.data = data;
}
@Override
public String toString() {
return content;
}
}
// HTTP Response类
private static class Response {
public final int statusCode; // 返回的状态码
public final String header; // 返回的Header
public final String data; // 返回的Body
public Response(int statusCode, String header, String data) {
this.statusCode = statusCode;
this.header = header;
this.data = data;
}
@Override
public String toString() {
return data;
}
}
}
说明
- 由于只需要建立一个HTTP连接,所以选择使用单实例;
- setHandler用来将Activity创建的Handler,用来传递数据;
- 由于需要发送心跳,所以开了个线程,创建了请求队列;
- 接受GET请求返回的Body有多种方式,可以根据需要选择。上面的代码为了接受二进制数据,使用了ISO-8859-1编码,如果是文本,需要解码;
- 代码中的"error"和Defines.ERROR用于判断连接异常;