1、封装前准备
1.1、定义一个请求方法的枚举类型
package com.gau.simplehttp.http;
public enum HttpMethod {
GET, POST
}
1.2、定义一个响应结果实体,用于接收服务器返回的数据
package com.gau.simplehttp.http;
public class Response {
private final int code;
private final String message;
private final String method;
private final String contentType;
private final int contentLength;
private final String body;
public Response(Builder builder) {
this.code = builder.code;
this.message = builder.message;
this.method = builder.method;
this.contentType = builder.contentType;
this.contentLength = builder.contentLength;
this.body = builder.body;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public String getMethod() {
return method;
}
public String getContentType() {
return contentType;
}
public int getContentLength() {
return contentLength;
}
public boolean isSuccessful() {
return this.code >= 200 && this.code < 300;
}
public String getBody() {
return body;
}
public static class Builder {
private int code;
private String message;
private String method;
private String contentType;
private int contentLength;
private String body;
public Builder code(int code) {
this.code = code;
return this;
}
public Builder message(String message) {
this.message = message;
return this;
}
public Builder method(String method) {
this.method = method;
return this;
}
public Builder contentType(String contentType) {
this.contentType = contentType;
return this;
}
public Builder contentLength(int contentLength) {
this.contentLength = contentLength;
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public Response build() {
return new Response(this);
}
}
}
1.3、定义一个请求回调,其中Response为自己定义的响应结果
public interface HttpCallback {
void onComplete(Response response);
void onError(Throwable e);
}
2、封装ing
2.1、请求体的封装
package com.gau.simplehttp.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class Request {
private final static int CONNECT_TIME_OUT_MILLISECOND = 10000;
private final static int READ_TIME_OUT_MILLISECOND = 20000;
private String url;
private List<String> params;
private List<String> headers;
private String string;
private HttpMethod method;
private HttpURLConnection connection;
private static HttpCallback mHttpCallback;
private Request(Builder builder) {
this.url = builder.url;
this.params = builder.params;
this.headers = builder.headers;
this.method = builder.method;
this.string = builder.string;
}
public static Request newRequest(Builder builder) {
return newRequest(builder, null);
}
public static Request newRequest(Builder builder, HttpCallback httpCallback) {
mHttpCallback = httpCallback;
return new Request(builder);
}
/*
* 异步请求
*/
public void executeAsync() {
HttpAsyncTask asyncTask = new HttpAsyncTask(this, connection, mHttpCallback);
asyncTask.execute();
}
/*
* 同步请求
*/
public Response execute() throws IOException {
if (method == HttpMethod.POST) {
post();
} else {
get();
}
return response(connection);
}
/*
* get请求
*/
private void get() throws IOException {
URL requestUrl = new URL(getUrl(url));
connection = (HttpURLConnection) requestUrl.openConnection();
connection.setRequestMethod(String.valueOf(method));
connection.setConnectTimeout(CONNECT_TIME_OUT_MILLISECOND);
connection.setReadTimeout(READ_TIME_OUT_MILLISECOND);
connection.setDoInput(true);
connection.setUseCaches(false);
connectHeaders();
connection.connect();
}
/*
* get请求拼接url
*/
private String getUrl(String url) {
StringBuilder sb = new StringBuilder();
sb.append(url).append("?");
for (int i = 0; i < params.size(); i += 2) {
sb.append(params.get(i));
sb.append("=");
sb.append(params.get(i + 1));
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
/*
* post请求
*/
private void post() throws IOException {
URL requestUrl = new URL(url);
connection = (HttpURLConnection) requestUrl.openConnection();
connection.setRequestMethod(String.valueOf(method));
connection.setConnectTimeout(CONNECT_TIME_OUT_MILLISECOND);
connection.setReadTimeout(READ_TIME_OUT_MILLISECOND);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connectHeaders();
connection.connect();
postBody();
}
/*
* post请求上传数据
*/
private void postBody() throws IOException {
postForm();
postString();
}
/*
* 上传表单
*/
private void postForm() throws IOException {
if (params != null && params.size() > 0) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.size(); i += 2) {
sb.append(params.get(i));
sb.append("=");
sb.append(params.get(i + 1));
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
connection.getOutputStream().write(sb.toString().getBytes("GBK"));
}
}
/*
* 上传字符串,如json字符串
*/
private void postString() throws IOException {
if (string != null && !string.isEmpty()) {
connection.getOutputStream().write(string.getBytes("GBK"));
}
}
/*
* 设置请求头
*/
private void connectHeaders() {
if (headers != null && headers.size() > 0) {
for (int i = 0; i < headers.size(); i += 2) {
connection.setRequestProperty(headers.get(i), headers.get(i + 1));
}
}
}
/*
* 获取响应结果
*/
private Response response(HttpURLConnection connection) throws IOException {
Response resp = new Response.Builder()
.code(connection.getResponseCode())
.message(connection.getResponseMessage())
.method(connection.getRequestMethod())
.contentType(connection.getContentType())
.contentLength(connection.getContentLength())
.body(getResponseBody(connection.getInputStream()))
.build();
connection.disconnect();
return resp;
}
/*
* 获取响应的数据
*/
private String getResponseBody(InputStream stream) {
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line;
try {
while ((line = br.readLine()) != null) {
sb.append(line).append("\r\n");
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public static class Builder {
private String url;
private List<String> params = new ArrayList<>();
private List<String> headers = new ArrayList<>();
private HttpMethod method = HttpMethod.GET;
private String string;
public Builder url(String url) {
if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("url can not be null or empty");
}
this.url = url;
return this;
}
public Builder method(HttpMethod method) {
this.method = method;
return this;
}
public Builder params(String key, String value) {
params.add(key);
params.add(value);
return this;
}
public Builder headers(String key, String values) {
headers.add(key);
headers.add(values);
return this;
}
public Builder string(String string) {
this.string = string;
return this;
}
public Request build() {
return new Request(this);
}
}
}
Request包含同步请求和异步请求两种方式,其中异步请求采用的是AsyncTask实现。
2.2、异步的实现
package com.gau.simplehttp.http;
import android.os.AsyncTask;
import java.io.IOException;
import java.net.HttpURLConnection;
public class HttpAsyncTask extends AsyncTask<Void, Void, Response> {
private Request request;
private HttpURLConnection connection;
private HttpCallback httpCallback;
private Exception exception;
public HttpAsyncTask(Request request, HttpURLConnection connection, HttpCallback httpCallback) {
this.connection = connection;
this.request = request;
this.httpCallback = httpCallback;
}
@Override
protected Response doInBackground(Void... params) {
try {
if (request != null) {
return request.execute();
}
} catch (IOException e) {
if (connection != null) {
connection.disconnect();
}
exception = e;
}
return null;
}
@Override
protected void onPostExecute(Response response) {
super.onPostExecute(response);
if (response == null) {
if (httpCallback != null) {
if (exception != null) {
httpCallback.onError(exception);
} else {
httpCallback.onError(new Exception("UnKnown Exception"));
}
}
} else {
if (httpCallback != null) {
httpCallback.onComplete(response);
}
}
}
}
ps: 回调的结果是直接回调到主线程中,所以可以在回调方法里直接对UI进行操作。
3、测试代码
// 同步请求
new Thread(new Runnable() {
@Override
public void run() {
Request.Builder builder = new Request.Builder().url("https://www.baidu.com");
Request request = Request.newRequest(builder);
try {
Response response = request.execute();
if (response != null) {
if (response.isSuccessful()) {
Log.e(TAG, "response is success:" + response.getBody());
} else {
Log.e(TAG, "response is fail:" + response.getBody());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
// 异步请求
Request.Builder build = new Request.Builder()
.url("http://10.0.3.2:8080/TestProject/TestServlet")
.method(HttpMethod.POST)
.headers("User-Agent", "guochao-1.0")
.params("param1", "hello world")
.params("param2","bye bye world")
.string("{\"json\":\"string\"}");
Request.newRequest(build, new HttpCallback() {
@Override
public void onComplete(Response response) {
Log.e(TAG, "onComplete/response:" + response.getBody());
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError:" + e.getMessage());
}
}).executeAsync();
请求的参数可以通过调用builder.params("","")
传递,请求头通过builder.headers("","")
设置,最后通过request.execute()
同步发送请求或request.executeAsync()
异步发起请求。