简约之美Jodd-http--深入源码理解http协议
Jodd 是一个开源的 Java 工具集, 包含一些实用的工具类和小型框架。简单,却很强大! jodd-http是一个轻巧的HTTP客户端。现在我们以一个简单的示例从源码层看看是如何实现的? HttpRequest httpRequest = HttpRequest.get("http://jodd.org"=
System.out.println(response);//3.打印响应信息</span></pre>
构建一个get请求 先复习一下http请求报文的格式: 下图展示一般请求所带有的属性 调用get方法构建http请求:
"GET"
method方法如下:
.method =
set方法如下:
=
</span><span style="color: #ff0000;">// http method</span>
<span style="color: #0000ff;">int</span> ndx = destination.indexOf(' '<span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span> (ndx != -1<span style="color: #000000;">) {
method </span>= destination.substring(0<span style="color: #000000;">,ndx).toUpperCase();
destination </span>= destination.substring(ndx + 1<span style="color: #000000;">);
}
</span><span style="color: #ff0000;">// protocol</span>
<span style="color: #000000;">
<span style="color: #000000;">
<span style="color: #000000;">
<span style="color: #000000;">
上述方法,根据destination解析出一下几个部分: 1. 方法:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。 2. 协议:http或者https 3. 主机:请求的服务器地址 4. 端口:请求的服务器端口 5. 路径+查询参数,其中参数以“?”开头,使用“&”连接
发送请求 先熟悉一下http响应报文的格式: 响应首部一般包含如下内容:
(httpConnection ==
}
<span style="color: #000000;"> HttpResponse httpResponse; OutputStream outputStream =<span style="color: #000000;"> httpConnection.getOutputStream();
<span style="color: #000000;"> httpConnection.close(); }
1. 打开HttpConnection </span><span style="color: #008000;">/**</span><span style="color: #008000;">
* Opens a new {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> jodd.http.HttpConnection connection}
* using given {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> jodd.http.HttpConnectionProvider}.
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span><span style="color: #000000;"> HttpRequest open(HttpConnectionProvider httpConnectionProvider) {
</span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.httpConnection != <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> HttpException("Connection already opened"<span style="color: #000000;">);
}
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
</span><span style="color: #0000ff;">this</span>.httpConnectionProvider =<span style="color: #000000;"> httpConnectionProvider;
</span><span style="color: #ff0000;">this.httpConnection = httpConnectionProvider.createHttpConnection(this</span><span style="color: #000000;"><span style="color: #ff0000;">);</span>
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (IOException ioex) {
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> HttpException(ioex);
}
</span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;
}</span></pre>
判断是否有连接,若没有连接则创建一个新的连接。 2. 创建连接实现
HttpConnection createHttpConnection(HttpRequest httpRequest)
</span><span style="color: #0000ff;">if</span> (httpRequest.protocol().equalsIgnoreCase("https"<span style="color: #000000;">)) {
SSLSocket sslSocket </span>=<span style="color: #000000;"> createSSLSocket(httpRequest.host(),httpRequest.port());
sslSocket.startHandshake();
socket </span>=<span style="color: #000000;"> sslSocket;
} </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
socket </span>=<span style="color: #000000;"> createSocket(httpRequest.host(),httpRequest.port());
}
</span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> SocketHttpConnection(socket);
}</span></pre>
3. 创建socket 根据协议的不同,http使用SocketFactory创建socket,https使用SSLSocketFactory创建SSLSocket。最终使用SocketHttpConnection进行包装。 SocketHttpConnection继承自HttpConnection,实现了socket的输入输出流连接。注意:https创建完SSLSocket时需要进行握手。 SocketHttpConnection
</span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">final</span><span style="color: #000000;"> Socket socket;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> SocketHttpConnection(Socket socket) {
</span><span style="color: #0000ff;">this</span>.socket =<span style="color: #000000;"> socket;
}
</span><span style="color: #0000ff;">public</span> OutputStream getOutputStream() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> IOException {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> socket.getOutputStream();
}
</span><span style="color: #0000ff;">public</span> InputStream getInputStream() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> IOException {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> socket.getInputStream();
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> close() {
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
socket.close();
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (IOException ignore) {
}
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> setTimeout(<span style="color: #0000ff;">int</span><span style="color: #000000;"> milliseconds) {
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
socket.setSoTimeout(milliseconds);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (SocketException sex) {
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> HttpException(sex);
}
}
</span><span style="color: #008000;">/**</span><span style="color: #008000;">
* Returns <code>Socket</code> used by this connection.
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span><span style="color: #000000;"> Socket getSocket() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> socket;
}
} ?打开Connection的输出流发送信息,打开connection的输入流接受返回信息。 OutputStream outputStream =
<span style="color: #ff0000;">sendTo(outputStream);</span>
InputStream inputStream </span>= httpConnection.getInputStream();</pre>
发送过程: </span><span style="color: #008000;">/**</span><span style="color: #008000;">
* Sends request or response to output stream.
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> sendTo(OutputStream out) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> IOException {
Buffer buffer </span>= buffer(<span style="color: #0000ff;">true</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span> (httpProgressListener == <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
buffer.writeTo(out);
}
</span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
buffer.writeTo(out,httpProgressListener);
}
out.flush();
}</span></pre>
将缓冲区的数据写入输出流,并发送。 接受数据并读取报文内容:
} =
HttpResponse httpResponse </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> HttpResponse();
</span><span style="color: #008000;">//</span><span style="color: #008000;"> the first line</span>
<span style="color: #000000;"> String line; line =<span style="color: #000000;"> reader.readLine(); } <span style="color: #0000ff;">catch<span style="color: #000000;"> (IOException ioex) { <span style="color: #0000ff;">throw <span style="color: #0000ff;">new<span style="color: #000000;"> HttpException(ioex); }
小结 ? 从上面的代码,我们可以看出http使用socket来建立和destination的连接,然后通过连接的输出流和输入流来进行通信。 参考文献: 【1】http://www.it165.net/admin/html/201403/2541.html 【2】http://jodd.org/doc/http.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |