Java 在Netty服务器中未调用RequestHandler

Java 在Netty服务器中未调用RequestHandler,java,netty,Java,Netty,我正在Netty Http服务器上工作。我已经创建并注册了处理程序。但我没有看到请求击中处理程序 这是主课 public class NettyServer { private int port; private NettyServer(int port) { this.port = port; } public static void main(String[] args) throws Exception { int po

我正在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();
        }
    }
}
公共类NettyServer{
专用int端口;
专用NettyServer(int端口){
this.port=端口;
}
公共静态void main(字符串[]args)引发异常{
国际港口;
如果(args.length>0){
port=Integer.parseInt(args[0]);
}否则{
端口=8080;
}
新建NettyServer(端口).run();
}
private void run()引发异常{
EventLoopGroup bossGroup=新的NioEventLoopGroup();
EventLoopGroup workerGroup=新的NioEventLoopGroup();
试一试{
ServerBootstrap b=新的ServerBootstrap();
b、 组(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(新的ChannelInitializer()){
@凌驾
public void initChannel(SocketChannel ch)引发异常{
ch.pipeline().addLast(新的HttpMessageHandler(),新的CalculatorOperationHandler());
}
}).option(ChannelOption.SO_BACKLOG,128)。childOption(ChannelOption.SO_KEEPALIVE,true);
ChannelFuture f=b.bind(port.sync();
f、 通道().closeFuture().sync();
}最后{
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");
        }

    }
}
公共类HttpMessageHandler扩展了SimpleChannelInboundHandler{
受保护的无效channelRead0(ChannelHandlerContext ctx,FullHttpRequest msg)引发异常{
System.out.println(“你好”);
字符串uri=msg.uri();
HttpMethod HttpMethod=msg.method();
HttpHeaders=msg.headers();
if(HttpMethod.GET==HttpMethod){
字符串[]uriComponents=uri.split(“[?]”);
字符串端点=uriComponents[0];
字符串[]queryParams=uriComponents[1]。拆分(“&”);
if(“/calculate”.equalsIgnoreCase(端点)){
字符串[]firstQueryParam=queryParams[0]。拆分(“”);
字符串[]secondQueryParam=queryParams[1]。拆分(“”);
整数a=Integer.valueOf(firstQueryParam[1]);
整数b=整数.valueOf(secondQueryParam[1]);
字符串运算符=headers.get(“运算符”);
操作=新操作(a、b、操作员);
ctx.fireChannelRead(操作);
}
}否则{
抛出新的UnsupportedOperationException(“不支持HTTP方法”);
}
}
}
当我调用
localhost:8080/calculate?a=1&b=2时,我看不到控制台中打印的“hello”


这里出了什么问题?

您的问题是由于管道中缺少处理程序造成的

目前,管道中只有2个处理程序:

  • 处理
    FullHttpRequest
    对象的
    HttpMessageHandler
  • CalculatorOperationHandler
    ,用于处理
    操作
    对象
当来自浏览器的数据进入时,它作为
ByteBuf
对象进入,但您不处理此对象

要将
ByteBuf
转换为
FullHttpRequest
,您需要在管道中添加其他可以执行此操作的处理程序

您需要的第一个处理程序是
HttpServerCodec
,该类将
ByteBuf
对象转换为作为HTTP交换一部分的对象,例如头、尾随头和请求体

然后您需要添加一个
HttpObjectAggregator
,它将上述对象组合成一个
FullHttpRequest
,因此您只需要处理一个对象

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

如果您想查看任何层之间的流量,还可以添加一个
新的LoggingHandler(LogLevel.INFO)

注释不用于扩展讨论;这段对话已经结束。为什么这里没有使用HttpServerCodec和HttpObjectAggregator然后HttpServerCodec会自动添加HttpRequestEncoder和HttpRequestDecoder,并且由于该示例不处理HttpFullRequest的实例,所以它们不需要聚合器。您是说如果我不添加HttpServerCodec,我需要有一个自定义编码器和解码器添加?换句话说,如果我添加了ResponseEncoder和RequestDecoder,我就不需要HttpServerCodec了?顺便说一句,你是说HttpResponseEncoder而不是HttpRequestEncoder?这是一个结合了
HttpRequestDecoder
HttpResponseEncoder
,所以它基本上取代了它们。我还有一个类似的问题。但我找不到解决办法。