netty编程之实现HTTP服务

news/2024/9/23 14:25:40/
http://www.w3.org/2000/svg" style="display: none;">

写在前面

源码 。
http是应用层协议,是我们日常开发中直接用到最多的协议了。本文来看下通过netty如何实现。

1:程序

netty不仅仅提供了String相关的编解码器,还贴心的提供了http相关的编码器和解码器,直接拿来用就行了,所以使用netty来实现http服务还是比较简单的。

1.1:server

server main:

package com.dahuyuo.netty.httpserver.server;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class NettyServer {public static void main(String[] args) {new NettyServer().bing(7397);}private void bing(int port) {//配置服务端NIO线程组EventLoopGroup parentGroup = new NioEventLoopGroup(); //NioEventLoopGroup extends MultithreadEventLoopGroup Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));EventLoopGroup childGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(parentGroup, childGroup).channel(NioServerSocketChannel.class)    //非阻塞模式.option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new MyChannelInitializer());ChannelFuture f = b.bind(port).sync();System.out.println("netty http server start done on port: " + 7397);f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {childGroup.shutdownGracefully();parentGroup.shutdownGracefully();}}}

MyChannelInitializer:

package com.dahuyuo.netty.httpserver.server;import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;import java.nio.charset.Charset;public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel channel) {// 数据解码操作channel.pipeline().addLast(new HttpResponseEncoder());// 数据编码操作channel.pipeline().addLast(new HttpRequestDecoder());// 在管道中添加我们自己的接收数据实现方法channel.pipeline().addLast(new MyServerHandler());}}

HttpResponseEncoder,HttpRequestDecoder就是http响应和请求和编码器和解码器。MyServerHandler是自定义的inbound的消息处理器:

package com.dahuyuo.netty.httpserver.server;import io.netty.buffer.ByteBuf;
import io.netty.buffer.EmptyByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.*;import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;public class MyServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof HttpRequest) {DefaultHttpRequest request = (DefaultHttpRequest) msg;System.out.println("URI:" + request.getUri());System.err.println(msg);}if (msg instanceof HttpContent) {LastHttpContent httpContent = (LastHttpContent) msg;ByteBuf byteData = httpContent.content();if (!(byteData instanceof EmptyByteBuf)) {//接收msg消息byte[] msgByte = new byte[byteData.readableBytes()];byteData.readBytes(msgByte);System.out.println(new String(msgByte, Charset.forName("UTF-8")));}}String sendMsg = "我是netty实现的http server响应的内容啊!!!";FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK,Unpooled.wrappedBuffer(sendMsg.getBytes(Charset.forName("UTF-8"))));response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=UTF-8");response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);ctx.write(response);ctx.flush();}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {ctx.flush();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();cause.printStackTrace();}}

其中方法channelRead对http的请求信息做了解析,并输出了相关内容。最后写回了http的响应。

1.2:client

https://i-blog.csdnimg.cn/direct/1e064d05c64f4d8192f7daaf6b292584.png" alt="在这里插入图片描述" />

写在后面

参考文章列表


http://www.ppmy.cn/news/1517936.html

相关文章

2017年系统架构师案例分析试题一

目录 案例 【题目】 【问题 1】(12 分) 【问题 2】(13 分) 答案 【问题 1】答案 【问题 2】答案 相关推荐 案例 阅读以下关于软件架构评估的叙述&#xff0c;在答题纸上回答问题 1 和问题 2。 【题目】 某单位为了建设健全的公路桥梁养护管理档案&#xff0c;拟开发一套公…

代码随想录Day 29|leetcode题目:134.加油站、135.分发糖果、860.柠檬水找零、406.根据身高重建队列

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 第八章 贪心算法 part03二、题目题目一&#xff1a;134. 加油站解题思路&#xff1a;暴力方法贪心算法&#xff08;方法一&#xff09;贪心算法&#xff08;方法二&#xff09; 题目二&#xff1a…

第八章 Java多线程--锁--深入ReentrantReadWriteLock

目录 一、为什么要出现读写锁 二、读写锁的实现原理 三、写锁分析 1 写锁加锁流程概述 2 写锁加锁源码分析 3 写锁释放锁流程概述&释放锁源码 四、读锁分析 1 读锁加锁流程概述 1.1 基础读锁流程 1.2 读锁重入流程 1.3 读锁加锁的后续逻辑fullTryAcquireShared …

基于单片机的一氧化碳报警系统的设计与实现

摘 要&#xff1a; 一氧化碳对人体有害&#xff0c;尤其超标时会影响人们的健康 。 因此文章设计了一款基于单片机的一氧化氮报警器设计。 论文通过传感器检测一氧化碳浓度&#xff0c;经过 AD 转换&#xff0c;再把检测信号传递给单片机&#xff0c;经过分析处理&#xff0c…

layui栅格布局设置列间距不起作用

layui栅格布局支持设置列间距&#xff0c;只需使用预置类layui-col-space*即可。不过实际使用时却始终看不到效果。   根据layui官网文档的说明&#xff0c;只需要在行所在div元素的class属性中增加layui-col-space*即可出现列间距。如下图所示&#xff1a;   但是实际使用…

gptk是什么意思?Mac电脑如何在crossover里安装gptk2.0测试版?借助GPTK玩《原神》《黑神话悟空》游戏

很人多都听说使用 gptk2.0 beta 可以让《黑神话&#xff1a;悟空》等游戏的帧数提高&#xff0c;但自己并不知道如何安装&#xff0c;下面就给大家说下如何在crossover里安装 gptk2.0 beta 。安装前请先确认自己的电脑里已经安装好了crossover软件。 Game Porting Toolkit 简介…

深度全面讲解fs.readFileSync:Node.js中的同步文件读取

在Node.js中&#xff0c;fs模块是用于与文件系统交互的核心模块之一。它提供了一系列的方法用于文件的读取、写入、删除等操作。其中&#xff0c;fs.readFileSync是一个常用的同步方法&#xff0c;用于读取文件的内容。本文将深度全面讲解fs.readFileSync的使用&#xff0c;包括…

当不显示定义默认成员函数,会出现什么状况

目录 前言 构造与析构 拷贝构造与赋值重载 前言 C类中存在六大默认成员函数&#xff0c;当我们不显式定义&#xff0c;这些默认成员函数就不“干活”了吗&#xff1f;显然不是的&#xff0c;系统会生成默认成员函数&#xff0c;供给我们使用 首先我们要知道&#xff0c;成员…