1、背景
最近看了OkHttp源码,用的责任链模式,通过一些列拦截器(如重定向、缓存、网络链接等)实现网络请求,服务器连接部分是通过Socket,因此手动实现一下,加深记忆。
2、HTTP请求格式
贴一张图,来自HTTP请求格式
这个图就是实现的核心,通过Socket的输出流,把上述格式的字符串数据传给服务器,再通过输入流读取服务器的响应即可。
3、具体实现
3、1 封装一下请求
/**
* Description: http请求封装
* Author : pxq
* Date : 19-12-28 下午5:34
*/
public class Request {
//路径对应的URL
private URL url;
//原本请求的路径
private String path;
//请求协议
private String protocol;
//请求端口
private int port;
//请求主机
private String host;
//默认get请求
private Method method = Method.GET;
//额外的请求头
private Map<String, String> headers;
//额外的请求参数
private Map<String, String> params;
public Request(String url){
init(url);
}
private void init(String path) {
try {
this.path = path;
this.url = new URL(path);
this.port = getDefaultPort(this.url);
this.host = this.url.getHost();
this.protocol = this.url.getProtocol();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private static int getDefaultPort(URL url){
if (url.getPort() != -1){
return url.getPort();
}
//https
if ("https".equals(url.getProtocol())){
return 443;
}
//http
return 80;
}
.......getter setter省略.......
}
当传入一个api路径时,比如http://www.xxxxx.com/ 可以通过URL去解析这个路径拿到它的协议、端口、host等信息。需要注意的是当路径里没有显示的指明端口时,会返回-1,这里做了简单处理:http默认端口80和https默认端口443。