RequestHandler не вызывается на сервере Netty - PullRequest
1 голос
/ 30 марта 2019

Я работаю на 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();
        }
    }
}

HttpMessageHandler.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");
        }

    }
}

Я делаюне вижу "hello", напечатанного в консоли, когда я вызываю localhost:8080/calculate?a=1&b=2

что здесь не так?

1 Ответ

2 голосов
/ 30 марта 2019

Ваша проблема вызвана отсутствием обработчиков в вашем конвейере.

В данный момент у вас есть только 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), если хотите видеть трафик между любыми слоями.

...