在Netty服务器中不调用RequestHandler

问题描述 投票:1回答:1

我正在使用Netty Http服务器。我创建并注册了处理程序。但我没有看到请求击中处理程序

这是主要课程

public class NettyServer {

    private int port;

    private NettyServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws Exception {
        int port;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        } else {
            port = 8080;
        }
        new NettyServer(port).run();
    }

    private void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new HttpMessageHandler(),new CalculatorOperationHandler());
                }
            }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

HTTP message handler.Java

public class HttpMessageHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
        System.out.println("hello");
        String uri = msg.uri();
        HttpMethod httpMethod = msg.method();
        HttpHeaders headers = msg.headers();

        if (HttpMethod.GET == httpMethod) {

            String[] uriComponents = uri.split("[?]");
            String endpoint = uriComponents[0];
            String[] queryParams = uriComponents[1].split("&");

            if ("/calculate".equalsIgnoreCase(endpoint)) {

                String[] firstQueryParam = queryParams[0].split("=");
                String[] secondQueryParam = queryParams[1].split("=");

                Integer a = Integer.valueOf(firstQueryParam[1]);
                Integer b = Integer.valueOf(secondQueryParam[1]);
                String operator = headers.get("operator");

                Operation operation = new Operation(a, b, operator);
                ctx.fireChannelRead(operation);
            }
        } else {
            throw new UnsupportedOperationException("HTTP method not supported");
        }

    }
}

当我调用localhost:8080/calculate?a=1&b=2时,我没有在控制台中看到“你好”

这有什么不对?

java netty
1个回答
2
投票

您的问题是由管道中缺少处理程序引起的。

在您的时刻,您的管道中只有2个处理程序:

  • HttpMessageHandler,处理FullHttpRequest物体
  • CalculatorOperationHandler,处理Operation物体

当来自浏览器的数据进入时,它以ByteBuf对象的形式出现,但您不处理此对象!

要从ByteBuf转换为FullHttpRequest,您需要在管道中添加其他处理程序才能执行此操作。

您需要的第一个处理程序是HttpServerCodec,此类将ByteBuf对象转换为HTTP交换的一部分对象,如标题,尾随标题和请求主体。

然后你需要添加一个HttpObjectAggregator,它将上面的对象组合成一个FullHttpRequest,所以你只需要处理1个对象。

ch.pipeline().addLast(
    new HttpServerCodec(),
    new HttpObjectAggregator(65536), // Handle POST/PUT requests up 64KB
    new HttpMessageHandler(),
    new CalculatorOperationHandler()
);

如果要查看任何图层之间的流量,还可以添加new LoggingHandler(LogLevel.INFO)

© www.soinside.com 2019 - 2024. All rights reserved.