Tomcat原始碼分析使用NIO接收HTTP請求(五)----響應請求
阿新 • • 發佈:2022-12-10
本章的主要目標是為請求新增響應
第一步:新建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/結果如下
結束!!!