目錄
HTTP協議簡介
Http協議是基於TCP/IP協議基礎上用於超文本傳輸的應用層協議,主要有以下特點:
- 支持C/S模式
- 無狀態
- 靈活
- 簡單,直接在browser中指定url,攜帶請求參數或請求消息體就可與服務器通信
Http請求消息
HTTP請求報文由3部分組成(請求行+請求頭+請求體)
Http響應消息
HTTP的響應報文也由三部分組成(響應行+響應頭+響應體):
Http服務器實現
HttpServerCodec是對http消息編碼和解碼,相當於:HttpRequestDecoder和HttpResponseEncoder。因此在pipline.addLast時要麼開始就添加一個HttpServerCodec,或HttpRequestDecoder和HttpResponseEncoder分開添加。
public class HttpServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workGoup = new NioEventLoopGroup(8);
try{
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap
.group(bossGroup, workGoup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// HttpServerCodec 是 netty 提供的處理 http 的 編-解碼器
pipeline.addLast("httpServerCodec", new HttpServerCodec());
// 增加一個自定義的 handler
pipeline.addLast("MyHttpServerHandler", new MyHttpServerHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(7777).sync();
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workGoup.shutdownGracefully();
}
}
}
業務處理器
public class MyHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpRequest){
System.out.println("pipeline hashcode" + ctx.pipeline().hashCode() + " myHttpServerHandler hash=" + this.hashCode());
System.out.println("msg 類型:" + msg.getClass());
System.out.println("客戶端地址:" + ctx.channel().remoteAddress());
HttpRequest httpRequest = (HttpRequest) msg;
String uri = httpRequest.uri();
System.out.println("uri" + uri);
URI httpUri = new URI(uri);
// 處理請求
if ("/list".equals(httpUri.getPath())){
System.out.println("調用list接口");
return ;
}
if ("/add".equals(httpUri.getPath())){
System.out.println("調用add接口");
return ;
}
ByteBuf content = Unpooled.copiedBuffer("對不起, 資源沒有找到!", CharsetUtil.UTF_8);
// 構建一個響應
DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
httpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
ctx.writeAndFlush(httpResponse);
}
}
}
使用瀏覽器進行訪問:
案例
靜態服務服務器