无法使用 Netty 将 JSON POST 到服务器

Posted

技术标签:

【中文标题】无法使用 Netty 将 JSON POST 到服务器【英文标题】:Can't POST JSON to server using Netty 【发布时间】:2012-04-11 12:00:31 【问题描述】:

我遇到了一个非常非常基本的问题:使用 HttpRequestPOST 向使用 Netty 的服务器发送少量 JSON。

通道连接后,我准备这样的请求:

HttpRequest request = new DefaultHttpRequest(
    HttpVersion.HTTP_1_1, HttpMethod.POST, postPath);
request.setHeader(HttpHeaders.Names.CONTENT_TYPE, "application/json");
String json = "\"foo\":\"bar\"";
ChannelBuffer buffer = ChannelBuffers.copiedBuffer(json, CharsetUtil.UTF_8);
request.setContent(buffer);

channel.write(request);
System.out.println("sending on channel: " + json);

最后一行打印出"foo":"bar",这是格式正确的JSON。

但是,我使用 Flask 在 Python 中编写的一个非常简单的回显服务器会显示请求,但它没有 bodyjson 字段,就像无法将正文正确解析为 JSON。

当我简单地使用curl 发送相同的数据时,回显服务器会正​​确找到并解析 JSON:

curl --header "Content-Type: application/json" -d '"foo":"bar"' -X POST http://localhost:5000/post_path

我在 Netty 中的管道由以下组成:

return Channels.pipeline(
    new HttpClientCodec(),
    new MyUpstreamHandler(...));

MyUpstreamHandler 扩展 SimpleChannelUpstreamHandler 并且是在通道连接后尝试发送 HttpRequest 的位置。

再一次,我完全不知所措。任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

正如 Veebs 所说,您必须设置一些 http 标头,我也遇到了同样的问题并且丢失了几个小时,我使用以下代码让它工作:)。

    import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;

    ......  

    HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/post_path");

    final ChannelBuffer content = ChannelBuffers.copiedBuffer(jsonMessage, CharsetUtil.UTF_8);

    httpRequest.setHeader(CONTENT_TYPE, "application/json");
    httpRequest.setHeader(ACCEPT, "application/json");

    httpRequest.setHeader(USER_AGENT, "Netty 3.2.3.Final");
    httpRequest.setHeader(HOST, "localhost:5000");

    httpRequest.setHeader(CONNECTION, "keep-alive");
    httpRequest.setHeader(CONTENT_LENGTH, String.valueOf(content.readableBytes()));

    httpRequest.setContent(content);

    channel.write(httpRequest);

【讨论】:

【参考方案2】:

不确定您是否启用了 http keep alive on,但如果这样做,您可能必须在标头中发送内容长度。

【讨论】:

这确实是问题所在。我最初放了以下内容:request.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(buffer.getByteArray().length)); 但缓冲区的底层byte[] 似乎来自一个池,而不是从复制缓冲区的json 派生而来。因此,回首过去,它返回的是53,而不是13。此时,我省略了对setHeader 的调用,有点希望Netty 会根据传递给request.setContent 的参数简单地为我添加它。正如 Jestan 指出的,我必须使用 buffer.readableBytes()

以上是关于无法使用 Netty 将 JSON POST 到服务器的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Postman 将 POST json 请求发送到 restful api

使用 Retrofit 发送 POST 请求并接收 Json 响应无法使用响应数据我需要将其传递给另一个活动

Kotlin > Spring Boot > 使用路由器 DSL,POST 方法主体,无法将 JSON 转换为 POJO

将json参数发布到api使用post方法Swift 3

无法解析来自 jQuery Ajax POST 的 Json 结果

Netty SSL:具有自定义密钥库的Chat Client示例无法接受多个连接