自己用Java写一个HTTP服务器和MVC框架

自己刚实现了一个轻量级的嵌入式http服务器,Java语言,基于nio。

同时提供类似spring mvc的功能, 包括@Controller,@RequestMapping,参数注入等功能。


项目地址:LightWebServer


项目总计1700行java代码, {理解原理 + 不实现}三天左右,{理解原理 + 自己实现}需要一周左右。

自己用Java写一个HTTP服务器和MVC框架


下面分享一下自己的学习步骤:


1.学习nio相关知识

简单来说nio是用来处理socket连接的,包括:

  • 建立服务端和客户端之间的连接
  • 从socket读数据(读http request的数据)
  • 往socket写数据(写http response的数据)

注:服务端监听客户端发起的连接请求。浏览器,postman插件,idea的TEST RESTful Web Service插件,自己写的发送http请求的代码等都可以看成客户端。
nio学习路线:通道 -> 选择器 -> 缓冲区(千万不要按书中的顺序一开始就学缓冲区API, 头会晕的)。学完后用nio处理的这一部分完整代码在这。目前没有实现keep-alive,一个线程(选择器所在线程)管理多个通道(nio核心理念)。读取完一个请求后开一个线程(RequestHandler类)处理http请求。

public void read(SelectionKey key) throws IOException {
    SocketChannel client = (SocketChannel) key.channel();
    ThreadPool.execute(new RequestHandler(client, selector));
    key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);//目前一个请求对应一个socket连接,没有实现keep-alive
}

2.解析http请求(parse http request)

3.生成http响应(generate http response)

因为需要做springmvc中类似@Controller和@RequestMapping功能,所以需要做以下两件事

4.将响应写回给客户端

public void write(SelectionKey key) throws IOException {
    SocketChannel client = (SocketChannel) key.channel();
    Response response = (Response) key.attachment();//从key中取出response
    ByteBuffer byteBuffer = response.getResponseBuffer();
    if(byteBuffer.hasRemaining()){
        client.write(byteBuffer);
    }
    if(!byteBuffer.hasRemaining()){
        key.cancel();
        client.close();
    }
}

References

  1. HTTP规范
  2. nio教程