**
1. 使用 Netty 作为 web 服务器实例
1**. Netty 作为 web 服务器的流程图**
2. 实现代码
public void start() {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
try {
ChannelFuture future = bootstrap
.group(bossGroup,// bossGroup 负责管理所有的链接
workerGroup) // workerGroup 处理业务
.channel(NioServerSocketChannel.class)
//处理 客户端发送的数据
.childHandler(new MyServerChannelInitializer())
.bind(8080).sync();// 绑定端口 8080
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
// ==================================================
// 将拦截器 加入 plpeline 中
public class MyServerChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline() .addLast(new HttpRequestDecoder()) //http请求的解码器
ch.pipeline().addLast(new HttpObjectAggregator(1024 * 128))
ch.pipeline().addLast(new HttpResponseEncoder()) //http响应的编码器
ch.pipeline().addLast(new ChunkedWriteHandler()) //支持异步的大文件上传
ch.pipeline().addLast(new ServerHandler()); //传输,防止内存溢出
}
}
// ==================================================
public class ServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
//解析FullHttpRequest,得到请求参数
Map<String, String> paramMap = new RequestParser(request).parse();
String name = paramMap.get("name");
//构造响应对象
FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=utf-8");
StringBuilder sb = new StringBuilder();
sb.append("<h1>");
sb.append("你好," + name);
sb.append("</h1>");
httpResponse.content().writeBytes(Unpooled.copiedBuffer(sb, CharsetUtil.UTF_8));
ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE); //操作完成后,将channel 关闭
}
}
// ==================================================
// HTTP请求参数解析器, 支持GET, POST
public class RequestParser {
private FullHttpRequest fullReq;
// 构造一个解析器 * @param req
public RequestParser(FullHttpRequest req) {
this.fullReq = req;
}
/***
* 解析请求参数 * @return 包含所有请求参数的键值对, 如果没有参数,
*/
public Map<String, String> parse() throws Exception {
HttpMethod method = fullReq.method();
Map<String, String> parmMap = new HashMap<>();
if (HttpMethod.GET == method) {
// 是GET请求
QueryStringDecoder decoder = new QueryStringDecoder(fullReq.uri());
decoder.parameters().entrySet().forEach(entry -> {
// entry.getValue()是一个List, 只取第一个元素
parmMap.put(entry.getKey(), entry.getValue().get(0));
});
} else if (HttpMethod.POST == method) { // 是POST请求
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(fullReq);
decoder.offer(fullReq);
List<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();
for (InterfaceHttpData parm : parmList) {
Attribute data = (Attribute) parm;
parmMap.put(data.getName(), data.getValue());
}
} else { // 不支持其它方法
throw new RuntimeException("不支持其它方法"); // 这是个自定义的异常, 可删 掉这一行
}
return parmMap;
}
}