1. 程式人生 > 其它 >Tomcat原始碼分析使用NIO接收HTTP請求(五)----響應請求

Tomcat原始碼分析使用NIO接收HTTP請求(五)----響應請求

本章的主要目標是為請求新增響應
第一步:新建Http11OutputBuffer類
public class Http11OutputBuffer {
    protected final ByteBuffer headerBuffer;

    public Http11OutputBuffer () {
        headerBuffer = ByteBuffer.allocate(2048);
    }

    public ByteBuffer getHeaderBuffer() {
        sendStatus();
        byte[] body = ByteChunk.convertToBytes("<html><h1>Hello World!</h1></html>");
        String format 
= "EEE,dd MMM yyyy HH:mm:ss z"; SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US); headerBuffer.put(ByteChunk.convertToBytes("Content-Type: text/html")); headerBuffer.put((byte) '\r').put((byte) '\n'); headerBuffer.put(ByteChunk.convertToBytes("Content-Length:" + body.length)); headerBuffer.put((
byte) '\r').put((byte) '\n'); headerBuffer.put(ByteChunk.convertToBytes("Date:" + sdf.format(new Date()))); headerBuffer.put((byte) '\r').put((byte) '\n'); headerBuffer.put(ByteChunk.convertToBytes("Server:Apache/1.1")); headerBuffer.put((byte) '\r').put((byte) '\n'); headerBuffer.put(ByteChunk.convertToBytes(
"Connection:keep-alive")); headerBuffer.put((byte) '\r').put((byte) '\n'); headerBuffer.put((byte) '\r').put((byte) '\n'); headerBuffer.put(body); headerBuffer.flip(); byte[] bb = Arrays.copyOfRange(headerBuffer.array(), 0, headerBuffer.limit()); ByteBuffer result =ByteBuffer.allocate(bb.length); result.put(bb); return result; } public void sendStatus() { write(ByteChunk.convertToBytes("HTTP/1.1")); headerBuffer.put((byte) ' '); write(ByteChunk.convertToBytes("200")); headerBuffer.put((byte) ' '); write(ByteChunk.convertToBytes("OK")); headerBuffer.put((byte) '\r').put((byte) '\n'); } public void write(byte[] b) { headerBuffer.put(b); } }
第二步:在ByteChunk類中新增convertToBytes方法
public static final byte[] convertToBytes(String value) {
    byte[] result = new byte[value.length()];
    for (int i = 0; i < value.length(); i++) {
        result[i] = (byte) value.charAt(i);
    }
    return result;
}
第三步:在Poller中新建cancelledKey方法。並在processKey方法中進行呼叫
public void cancelledKey(SelectionKey key) {
    NioSocketWrapper ka = null;
    try {
        ka = (NioSocketWrapper) key.attachment();
        if (ka != null) {
            System.out.println("************************************************");
            NioChannel nioChannel = ka.getSocket();
            Http11OutputBuffer ho = new Http11OutputBuffer();
            ByteBuffer bb = ho.getHeaderBuffer();
            System.out.println("=====" + bb.capacity());
            System.out.println(new String(bb.array(), StandardCharsets.UTF_8));
            int cout=0;
            bb.flip();
            while(bb.hasRemaining()) {
                cout = nioChannel.write(bb);
                Thread.sleep(2000);
                System.out.println("等待。。。。。。" + cout);
            }
            nioChannel.close();
        }
    } catch (Exception e) {

    }
}

 第四步:修改NioChannel的write方法

@Override
public int write(ByteBuffer src) throws IOException {
     return sc.write(src);
}
使用瀏覽器訪問http://localhost:8000/結果如下
結束!!!