基于netty实现http服务器

导入netty4的依赖

<dependency>
	   <groupId>io.netty</groupId>
	   <artifactId>netty-all</artifactId>
	   <version>4.1.28.Final</version>
</dependency>

服务端

/**
 * http服务器
 */
public class Server {

    //线程组
    private static final EventLoopGroup group = new NioEventLoopGroup();

    //服务端启动类
    private static final ServerBootstrap bootstrap = new ServerBootstrap();

    //监听端口
    private static final int PORT = 6789;

    private static final ServerHandler serverHandler = new ServerHandler();

    //SSL开关
    private static final boolean SSL = true;

    public static void start() throws InterruptedException, CertificateException, SSLException {
        //配置SSL
        final SslContext sslCtx;
        if (SSL) {
            //netty为我们提供的ssl加密,缺省
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            sslCtx = SslContextBuilder.forServer(ssc.certificate(),
                    ssc.privateKey()).build();
        } else {
            sslCtx = null;
        }

        //设置线程组
        bootstrap.group(group)
                //设置Nio方式的通道监听客户端连接
                .channel(NioServerSocketChannel.class)
                //设置端口
                .localAddress(new InetSocketAddress(PORT))
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        ChannelPipeline pipeline = nioSocketChannel.pipeline();

                        //验证SSL
                        if (sslCtx != null) {
                            pipeline.addLast(sslCtx.newHandler(nioSocketChannel.alloc()));
                        }

                        //对http请求进行解码
                        pipeline.addLast("decode", new HttpRequestDecoder());

                        //对http请求进行编码
                        pipeline.addLast("encode", new HttpResponseEncoder());

                        //对http进行聚合,设置最大聚合字节长度为10M
                        pipeline.addLast(new HttpObjectAggregator(10 * 1024 * 1024));

                        //开启http内容压缩
                        pipeline.addLast(new HttpContentCompressor());

                        //添加自定义处理器
                        pipeline.addLast(serverHandler);
                    }
                });

        System.out.println("服务端已经启动......");

        //阻塞方法,直到监听到指定的端口有连接
        ChannelFuture channel = bootstrap.bind().sync();

        //关闭通道
        channel.channel().closeFuture().sync();
    }


    public static void main(String[] args) throws InterruptedException, CertificateException, SSLException {
        Server.start();
    }

}

服务端处理器

/**
 * 服务端处理器
 */

@ChannelHandler.Sharable
public class ServerHandler extends ChannelInboundHandlerAdapter {

    private static String result = "";


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("已经获取到客户端连接......");
    }


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        FullHttpRequest request = (FullHttpRequest) msg;
        try {
            String uri = request.uri();
            HttpMethod method = request.method();

            if (!"/test".equalsIgnoreCase(uri)) {
                result = "路径找不到";
                send(ctx, HttpResponseStatus.BAD_REQUEST, result);
                return;
            }

            //get请求
            if (HttpMethod.GET.equals(method)) {
                result = "get请求: " + System.getProperty("line.separator") + RespConstant.getNews();
                send(ctx, HttpResponseStatus.OK, result);
            } else if (HttpMethod.POST.equals(method)) {
                //.....
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            request.release();
        }

    }

    //响应
    private void send(ChannelHandlerContext ctx, HttpResponseStatus status, String result) {
        //聚合响应,并设置http配置
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(result, CharsetUtil.UTF_8)
        );

        //设置响应headers
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=UTF-8");

        //添加监听,等所有数据全部响应完了之后再关闭资源
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}

响应工具类

/**
 * 响应消息
 */
public class RespConstant {
    private static final String[] NEWS = {
            "她那时候还太年轻,不知道所有命运赠送的礼物,早已在暗中标好了" +
                    "价格。——斯蒂芬·茨威格《断头皇后》",
            "这是一个最好的时代,也是一个最坏的时代;" +
                    "这是一个智慧的年代,这是一个愚蠢的年代;\n" +
                    "这是一个信任的时期,这是一个怀疑的时期;" +
                    "这是一个光明的季节,这是一个黑暗的季节;\n" +
                    "这是希望之春,这是失望之冬;" +
                    "人们面前应有尽有,人们面前一无所有;\n" +
                    "人们正踏上天堂之路,人们正走向地狱之门。 —— 狄更斯《双城记》",
    };

    private static final Random R = new Random();

    public static String getNews() {
        return NEWS[R.nextInt(NEWS.length)];
    }

}

猜你喜欢

转载自blog.csdn.net/qq_28822933/article/details/83588815