Netty将HttpRequest转换为ByteBuf

时间:2015-03-24 10:32:21

标签: java netty

在我的应用程序中,我需要在套接字上接收一个字节数组,将其解析为HttpRequest以执行一些检查,如果检查通过,则返回字节数组并再做一些工作。

该应用程序基于NETTY(这是一项要求)。

我的第一个想法是创建一个这样的管道:

  1. HttpRequestDecoder(从ByteBuf解码到HttpRequest)
  2. MyHttpRequestHandler(自己检查HttpRequest)
  3. HttpRequestEncoder(将HttpRequest编码为ByteBuf)
  4. MyButeBufHandler(使用ByteBuf工作)
  5. 然而,HttpRequestEncoder扩展了ChannelOutboundHandlerAdapter,因此不会为入站数据调用它。

    我该如何完成这项任务? 避免解码和重新编码请求会很好。

    此致 的Massimiliano

3 个答案:

答案 0 :(得分:1)

EmbeddedChannel中使用MyHttpRequestHandler

EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder());    ch.writeOutbound(MSG);    ByteBuf encoded = ch.readOutbound();

您必须将EmbeddedChannel保留为MyHttpRequestEncoder的成员变量,因为HttpRequestEncoder是有状态的。另外,请在使用完毕后关闭EmbeddedChannel(可能是channelInactive()方法。)

答案 1 :(得分:0)

我只需对一些HttpObjects进行编码和解码,并对它进行了一些努力。 解码器/编码器有状态的提示非常有价值。

这就是为什么我以为我会在这里添加我的发现。也许这对其他人有帮助。

我将RequestEncoder和ResponseDecoder声明为类成员,但它仍然无法正常工作。直到我记得我使用en / decoders的特定处理程序是共享的......

这就是我最终的工作方式。我的sequenceNr用于区分不同的请求。我为每个请求创建一个编码器和一个解码器,并将它们保存在HashMap中。使用我的sequenceNr,我能够始终为同一请求获得相同的解码器/编码器。处理LastContent对象后,不要忘记关闭并从Map中删除de / encoder通道。

@ChannelHandler.Sharable
public class HttpTunnelingServerHandler extends ChannelDuplexHandler {
private final Map<Integer, EmbeddedChannel> decoders = Collections.synchronizedMap(new HashMap<Integer, EmbeddedChannel>());
private final Map<Integer, EmbeddedChannel> encoders = Collections.synchronizedMap(new HashMap<Integer, EmbeddedChannel>());
.
.
//Encoding
if (!encoders.containsKey(currentResponse.getSequenceNr())) {
        encoders.put(currentResponse.getSequenceNr(), new EmbeddedChannel(new HttpResponseEncoder()));
    }
    EmbeddedChannel encoderChannel = encoders.get(currentResponse.getSequenceNr());
    encoderChannel.writeOutbound(recievedHttpObject);
    ByteBuf encoded = (ByteBuf) encoderChannel.readOutbound();
.
.
//Decoding
if (!decoders.containsKey(sequenceNr)) {
        decoders.put(sequenceNr, new EmbeddedChannel(new HttpRequestDecoder()));
        }
        EmbeddedChannel decoderChannel = decoders.get(sequenceNr);
        decoderChannel.writeInbound(bb);
        HttpObject httpObject = (HttpObject) decoderChannel.readInbound();

}

答案 2 :(得分:0)

如何将 EmbeddedChannel 作为处理程序通道的属性,而不是 HashMap。与您声称解决有状态编码器/解码器的问题不一样吗?

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
      ctx.channel().attr(EMBEDED_CH).set( new EmbeddedChannel(new HttpRequestDecoder()));
      super.channelActive(ctx);
}
    
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
      EmbeddedChannel embedCh = ctx.channel().attr(EMBEDED_CH).get();
      if (embedCh != null) {
          embedCh.close();
      }

      super.channelInactive(ctx);
}