Netty - 如何检测/提取帖子的内容?
Netty - how to detect / extract contents of posts?
我使用的是 Netty 5.0,对它的 http 功能还是陌生的。
我需要通过 json 字符串在 Netty 服务器和 JavaScript 应用程序之间进行通信。
服务器处理程序非常简单,如下代码:
public class HttpServerHandler extends SimpleChannelInboundHandler<Object> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg);
}
}
初始化程序代码:
public class NettyHttpServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder(Charset.forName("UTF-8")));
pipeline.addLast("encoder", new StringEncoder(Charset.forName("UTF-8")));
pipeline.addLast("handler", new HttpServerHandler());
}
}
每当客户端通过 post 方法发送 json 字符串时,服务器会打印出:
POST / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 51
Origin: http://127.0.0.1:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */ *
Referer: http://127.0.0.1:8888/MyWebApp02.html
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
{"cmd":"he", "ver":1, "dvt":3}
我需要的只是最后一行,json 字符串。但是,服务器接收到的输入是多字符串,我无法将它们转换为高级结构(例如 HttpRequest
)来获取该内容。我可以解析/检查所有字符串以检测 json 字符串,但看起来这是最糟糕的方法。我曾尝试改进代码(例如使用 SimpleChannelInboundHandler<FullHttpRequest>
、删除 DelimiterBasedFrameDecoder
)但到目前为止运气不佳。
要制作网络服务器,您应该使用HttpServerCodec
in combination with optionally a HttpObjectAggregator
。
您的 ChannelInitializer
应如下所示:
public class NettyHttpServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("http", new HttpServerCodec());
// optional, makes life easier
pipeline.addLast("dechunker", new HttpObjectAggregator(65536));
pipeline.addLast("handler", new HttpServerHandler());
}
}
如果存在 HttpObjectAggregator
,您的处理程序将处理 FullHttpRequest
,或不同类型的 HttpRequest
消息(这更难,请参见 this 示例)。
我的回答主要集中在我们收到的 FullHttpRequest
。
收到 FullHttpRequest
时,我们可以做一些事情:
- 使用
request.getUri()
获取 uri
- 获取
request.getMethod()
使用的HTTP方法
- 使用
request.headers()
获取 headers
- 使用
request.content()
获取POST/PUT请求的内容
要回答你的问题,你应该先调用request.getMethod()
检查方法是POST还是PUT,然后调用request.content()
获取内容。
示例:
public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
if(msg.getMethod().equals(HttpMethod.POST) || msg.getMethod().equals(HttpMethod.PUT)) {
System.out.println(msg.content().toString(Charset.forName("UTF-8")));
}
}
}
我使用的是 Netty 5.0,对它的 http 功能还是陌生的。 我需要通过 json 字符串在 Netty 服务器和 JavaScript 应用程序之间进行通信。
服务器处理程序非常简单,如下代码:
public class HttpServerHandler extends SimpleChannelInboundHandler<Object> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg);
}
}
初始化程序代码:
public class NettyHttpServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder(Charset.forName("UTF-8")));
pipeline.addLast("encoder", new StringEncoder(Charset.forName("UTF-8")));
pipeline.addLast("handler", new HttpServerHandler());
}
}
每当客户端通过 post 方法发送 json 字符串时,服务器会打印出:
POST / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 51
Origin: http://127.0.0.1:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */ *
Referer: http://127.0.0.1:8888/MyWebApp02.html
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
{"cmd":"he", "ver":1, "dvt":3}
我需要的只是最后一行,json 字符串。但是,服务器接收到的输入是多字符串,我无法将它们转换为高级结构(例如 HttpRequest
)来获取该内容。我可以解析/检查所有字符串以检测 json 字符串,但看起来这是最糟糕的方法。我曾尝试改进代码(例如使用 SimpleChannelInboundHandler<FullHttpRequest>
、删除 DelimiterBasedFrameDecoder
)但到目前为止运气不佳。
要制作网络服务器,您应该使用HttpServerCodec
in combination with optionally a HttpObjectAggregator
。
您的 ChannelInitializer
应如下所示:
public class NettyHttpServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("http", new HttpServerCodec());
// optional, makes life easier
pipeline.addLast("dechunker", new HttpObjectAggregator(65536));
pipeline.addLast("handler", new HttpServerHandler());
}
}
如果存在 HttpObjectAggregator
,您的处理程序将处理 FullHttpRequest
,或不同类型的 HttpRequest
消息(这更难,请参见 this 示例)。
我的回答主要集中在我们收到的 FullHttpRequest
。
收到 FullHttpRequest
时,我们可以做一些事情:
- 使用
request.getUri()
获取 uri
- 获取
request.getMethod()
使用的HTTP方法
- 使用
request.headers()
获取 headers
- 使用
request.content()
获取POST/PUT请求的内容
要回答你的问题,你应该先调用request.getMethod()
检查方法是POST还是PUT,然后调用request.content()
获取内容。
示例:
public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
if(msg.getMethod().equals(HttpMethod.POST) || msg.getMethod().equals(HttpMethod.PUT)) {
System.out.println(msg.content().toString(Charset.forName("UTF-8")));
}
}
}