0 概述

HTTP(超文本传输协议)是建立在TCP传输协议之上的应用层协议,由于其简单、灵活,其应用也非常之广泛。本文主要讲解如何用Netty 实现一个简单的http服务器。

1 http 请求消息

Http的请求由三部分组成:请求行、消息头、请求正文(body)。
请求行以一个方法开头,以空格分开,后面跟着请求URI和协议版本,格式为:Method(方法) Request-URI (统一资源标识符) HTTP-version(请求版本) CRLF(换行符)。

GET / HTTP/1.1
POST / HTTP/1.1

请求方法有多种,各种方法如下:

  • GET 请求获取Request-URI 所标识的资源。
  • POST 在Request-URI 所标识的资源后附加新的提交数据
  • HEAD 请求获取由Request-URI 所标识的资源相应消息报头
  • PUT 请求服务器存储一个资源,并用Request-URI作为其标识。
  • DELETE 请求服务器删除Request-URI 所标识的资源。
  • TRACE:请求服务器回收到的请求信息,主要用于测试或者诊断
  • CONNECT 保留将来使用
  • OPTIONS 请求查询服务器性能或者查询与资源相关的选项需求。

下面是一个http 请求消息(没有请求正文),请求行后面都是请求头。

GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8

2 http 响应消息

HTPP响应消息也是由3部分组成,分别是:状态行、消息报头、响应正文。
状态行的格式为: HTTP-version Status-Code Reason-Phrase CRLF.
具体如下

HTTP/1.1 200 OK
HTTP/1.1 404 Not Found

状态码由三位数字组成,第一个数字表示响应类别,有五种可能取值。

  • 1xx:指示信息。表示请求已经接受,继续处理。
  • 2xx :成功。表示请求已经被成功接收,理解、接受
  • 3xx :重定向。要完成请求必须进行进一步的操作。
  • 4xx:客户端错误,请求有语法错误,或者请求无法完成。
  • 5xx:服务器错误。服务器未能处理。

3 netty 实现http服务器

服务端实现

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpServerCodec;/*** Created by apple on 17/10/21.*/
public class HttpServer {public static void start(final int port) throws Exception {EventLoopGroup boss = new NioEventLoopGroup();EventLoopGroup woker = new NioEventLoopGroup();ServerBootstrap serverBootstrap = new ServerBootstrap();try {serverBootstrap.channel(NioServerSocketChannel.class).group(boss, woker).childOption(ChannelOption.SO_KEEPALIVE, true).option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("http-decoder",new HttpServerCodec());ch.pipeline().addLast(new HttpServerHandler());}});ChannelFuture future = serverBootstrap.bind(port).sync();future.channel().closeFuture().sync();} finally {boss.shutdownGracefully();woker.shutdownGracefully();}}public static void main(String[] args) throws Exception {start(8080);}
}

HttpServerHandler 类

import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;import java.util.HashMap;
import java.util.Map;/*** Created by apple on 17/10/21.*/
public class HttpServerHandler extends ChannelInboundHandlerAdapter {private String content = "hello world";private final static String LOC = "302";private final static String NOT_FOND = "404";private final static String BAD_REQUEST = "400";private final static String INTERNAL_SERVER_ERROR = "500";private static Map<String, HttpResponseStatus> mapStatus = new HashMap<String, HttpResponseStatus>();static {mapStatus.put(LOC, HttpResponseStatus.FOUND);mapStatus.put(NOT_FOND, HttpResponseStatus.NOT_FOUND);mapStatus.put(BAD_REQUEST, HttpResponseStatus.BAD_REQUEST);mapStatus.put(INTERNAL_SERVER_ERROR, HttpResponseStatus.INTERNAL_SERVER_ERROR);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof HttpRequest) {HttpRequest request = (HttpRequest) msg;boolean keepaLive = HttpUtil.isKeepAlive(request);System.out.println("method" + request.method());System.out.println("uri" + request.uri());String uri = request.uri().replace("/", "").trim();FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);if (mapStatus.get(uri) != null) {httpResponse.setStatus(mapStatus.get(uri));httpResponse.content().writeBytes(mapStatus.get(uri).toString().getBytes());} else {httpResponse.content().writeBytes(content.getBytes());}//重定向处理if (httpResponse.status().equals(HttpResponseStatus.FOUND)) {httpResponse.headers().set(HttpHeaderNames.LOCATION, "https://www.baidu.com/");}httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=UTF-8");httpResponse.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, httpResponse.content().readableBytes());if (keepaLive) {httpResponse.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);ctx.writeAndFlush(httpResponse);} else {ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE);}}}}

启动服务后,可以通过浏览器测试如下
http://127.0.0.1:8080/302

netty实现http服务器相关推荐

  1. 【Netty】使用 Netty 开发 HTTP 服务器 ( HTTP 请求过滤 )

    文章目录 一. HTTP 服务器请求过滤功能 1 . HTTP 服务器资源请求过滤 2 . HTTP 请求过滤方法 二. HTTP 服务器 ( 资源过滤 ) 代码实现 1 . 服务器主程序 2 . 服 ...

  2. 【Netty】使用 Netty 开发 HTTP 服务器

    文章目录 一. HTTP 服务器开发 二. HTTP 服务器代码分析 1 . Netty 开发 HTTP 服务器与 TCP 服务器对比 2 . ChannelInitializer 设置 3 . 自定 ...

  3. netty系列之:使用netty搭建websocket服务器

    文章目录 简介 netty中的websocket websocket的版本 FrameDecoder和FrameEncoder WebSocketServerHandshaker WebSocketF ...

  4. Netty构建游戏服务器(一)--基本概念与原理

    一,Netty是什么 1,Netty是由 JBOSS 提供的一个 java开源 框架. 2,Netty是JAR包,一般使用ALL-IN-ONE的JAR包就可以开发了. 3,Netty不需要运行在Tom ...

  5. 【Netty系列】使用Netty搭建WebSocket服务器

    使用Netty搭建WebSocket服务器 引入netty的依赖 <dependency><groupId>io.netty</groupId><artifa ...

  6. 4、netty编写http服务器、增加压缩支持、netty编写client、netty添加SL/TLS保护https支持

    注:源代码来自享学课堂,学习之后所做笔记,方便回顾,也给大家一个参考 目录 1 netty编写http服务器 1.1 主函数 1.2 ServerHandlerInit 1.3 服务端自定义BusiH ...

  7. 【Netty】五、Netty实现Http服务器

    Netty实现http服务器 一.Netty实现hhttp服务器 代码演示 HttpServer HttpServerHandler HttpServerInitializer (http请求解码和编 ...

  8. netty 文件传输服务器,Netty之二进制文件传输

    传输会话简要 客户端发起一个文本请求给服务器端, 服务器端解析里面文本, 返回文件给客户端, 客户端解析文件 服务器端 因为示例文件比较小, 所以没有做分段传输, 而是直接一次性把整个文件byte[] ...

  9. 56. Netty源代码分析-服务器初始化 NioEventLoopGroup实例化

    一. 代码下载 Netty代码下载和编译参考前一篇Netty文章 https://blog.51cto.com/483181/2112163 二. 服务器代码分析 2.1 服务器代码编写 一般Nett ...

  10. 基于Netty的http服务器

    2019独角兽企业重金招聘Python工程师标准>>> 根据netty一个官方例子改编 //html文件位置 public class Config {public static S ...

最新文章

  1. 删除排除链表中的重复元素
  2. 阿里百川IMSDK--自定义群聊界面
  3. IntelliJ IDEA的安装详解
  4. stm8s电机库vtimer_SetTimer()函数的使用
  5. 迅雷手机版苹果版_迅雷IOS版恢复下载,又能用苹果手机下载电影愉快追剧了
  6. 2021秋招----hr面试总结
  7. 中国银联Applepay客户端接入
  8. GAMES101 Lec6 反走样与深度缓冲
  9. VBA按列名称或是按表格标题给EXCEL表格做排序
  10. python warning
  11. Ruby+Watir搭建自动化测试框架
  12. ABAP字符串系列操作
  13. php笔试面试题大全
  14. 电脑反复出现蓝屏重启现象
  15. Java代码---求数组中的平均值
  16. Android连接、断开蓝牙扫描枪时屏幕刷新
  17. RocketMQ自动创建topic原理-TBW102
  18. 介绍一个开源的在线文档编辑器Etherpad
  19. 【Proteus仿真】利用加法计数器74XX160的级联实现2位计数
  20. Mysql 1067系统错误终极解决方案全集

热门文章

  1. rainmeter频谱动效和动态挂件
  2. 【前端学习-函数】js基础学习笔记
  3. 四位共阳极数码管显示函数_单片机利用四位共阳极得数码管显示2016
  4. 原创【歌词类】雪中吟
  5. 台湾大学开放式课程C语言,国立台湾大学-台大开放式课程.doc
  6. Morphia DAOs
  7. 庞贝古城千年废墟复活:VR模型与眼动追踪复现被火山灰掩埋的建筑
  8. 我的非计算机科班好友,斩获了十几个 offer
  9. 微服务的技术架构路线
  10. keil5库文件安装失败_iPad iPhone如何清理垃圾 iPad iPhone清理垃圾文件办法【详解】...