?? requesthandler.java
字號:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class RequestHandler implements Handler {
private ChannelIO channelIO;
private ByteBuffer requestByteBuffer = null; //存放HTTP請求的緩沖區(qū)
private boolean requestReceived = false; //是否已經(jīng)接收到了所有的HTTP請求
private Request request = null; //表示HTTP請求
private Response response = null; //表示HTTP響應
RequestHandler(ChannelIO channelIO) {
this.channelIO = channelIO;
}
/*
* 接收HTTP請求,如果已經(jīng)接收到了所有的HTTP請求數(shù)據(jù),就返回true,否則返回false
*/
private boolean receive(SelectionKey sk) throws IOException {
ByteBuffer tmp = null;
if (requestReceived)return true; //如果已經(jīng)接收到所有HTTP請求數(shù)據(jù),返回true
//如果已經(jīng)讀到通道的末尾,或者已經(jīng)讀到HTTP請求數(shù)據(jù)的末尾標志“\r\n”,就返回true
if ((channelIO.read() < 0) || Request.isComplete(channelIO.getReadBuf())) {
requestByteBuffer = channelIO.getReadBuf();
return (requestReceived = true);
}
return false;
}
/*
* 通過Request類的parse()方法,解析requestByteBuffer中的HTTP請求數(shù)據(jù),構造相應的Request對象
*/
private boolean parse() throws IOException {
try {
request = Request.parse(requestByteBuffer);
return true;
} catch (MalformedRequestException x) {
//如果HTTP請求的格式不正確,就發(fā)送錯誤信息
response = new Response(Response.Code.BAD_REQUEST,
new StringContent(x));
}
return false;
}
/*
* 創(chuàng)建HTTP響應
*/
private void build() throws IOException {
Request.Action action = request.action();
//僅僅支持GET和HEAD請求方式
if ((action != Request.Action.GET) &&
(action != Request.Action.HEAD)){
response = new Response(Response.Code.METHOD_NOT_ALLOWED,
new StringContent("Method Not Allowed"));
}else{
response = new Response(Response.Code.OK,
new FileContent(request.uri()), action);
}
}
/* 接收HTTP請求,發(fā)送HTTP響應 */
public void handle(SelectionKey sk) throws IOException {
try {
if (request == null) { //如果還沒有接收到HTTP請求的所有數(shù)據(jù)
//接收HTTP請求
if (!receive(sk))return;
requestByteBuffer.flip();
//如果成功解析了HTTP請求,就創(chuàng)建一個Response對象
if (parse())build();
try {
response.prepare(); //準備HTTP響應的內(nèi)容
} catch (IOException x) {
response.release();
response = new Response(Response.Code.NOT_FOUND,
new StringContent(x));
response.prepare();
}
if (send()) {
//如果HTTP響應沒有發(fā)送完畢,則需要注冊寫就緒事件,
//以便在寫就緒事件發(fā)生時繼續(xù)發(fā)送數(shù)據(jù)
sk.interestOps(SelectionKey.OP_WRITE);
} else {
//如果HTTP響應發(fā)送完畢,就斷開底層的連接,并且釋放Response占用的資源
channelIO.close();
response.release();
}
} else { //如果已經(jīng)接收到HTTP請求的所有數(shù)據(jù)
if (!send()) { //如果HTTP響應發(fā)送完畢
channelIO.close();
response.release();
}
}
} catch (IOException x) {
x.printStackTrace();
channelIO.close();
if (response != null) {
response.release();
}
}
}
/* 發(fā)送HTTP響應,如果全部發(fā)送完畢,就返回false,否則返回true */
private boolean send() throws IOException {
return response.send(channelIO);
}
}
/****************************************************
* 作者:孫衛(wèi)琴 *
* 來源:<<Java網(wǎng)絡編程精解>> *
* 技術支持網(wǎng)址:www.javathinker.org *
***************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -