Json 无法使用netty读取http客户端中的响应
我可以通过与服务器的连接写入http请求,但无法从服务器读取响应(不确定是否有响应)。。我如何检查它,然后再阅读它?我的服务器正在返回json作为响应 客户端代码:Json 无法使用netty读取http客户端中的响应,json,httprequest,netty,httpresponse,Json,Httprequest,Netty,Httpresponse,我可以通过与服务器的连接写入http请求,但无法从服务器读取响应(不确定是否有响应)。。我如何检查它,然后再阅读它?我的服务器正在返回json作为响应 客户端代码: public class NettyClient { public static void main(String[] args) throws Exception { URI uri = new URI("http://myurl.com/v1/v2?param1=value1");
public class NettyClient {
public static void main(String[] args) throws Exception {
URI uri = new URI("http://myurl.com/v1/v2?param1=value1");
String scheme = uri.getScheme() == null? "http" : uri.getScheme();
String host = uri.getHost();
int port = 443;
boolean ssl = "https".equalsIgnoreCase(scheme);
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new NettyClientInitializer(false));
// Make the connection attempt.
Channel ch = b.connect(host, port).sync().channel();
// Prepare the HTTP request.
HttpRequest request = new DefaultHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.GET, "http://myurl.com/v1/v2?param1=value1");
request.headers().set(HttpHeaders.Names.HOST, host);
request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
//request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);
// Send the HTTP request.
ch.writeAndFlush(request);
// Wait for the server to close the connection.
ch.closeFuture().sync();
} finally {
// Shut down executor threads to exit.
group.shutdownGracefully();
}
}
}
初始值设定项代码:
public class NettyClientInitializer extends ChannelInitializer<SocketChannel> {
private final boolean ssl;
public NettyClientInitializer(boolean ssl) {
this.ssl = ssl;
}
@Override
public void initChannel(SocketChannel ch) throws Exception {
// Create a default pipeline implementation.
ChannelPipeline p = ch.pipeline();
p.addLast("log", new LoggingHandler(LogLevel.INFO));
// Enable HTTPS if necessary.
/*
if (ssl) {
SSLEngine engine =
SecureChatSslContextFactory.getClientContext().createSSLEngine();
engine.setUseClientMode(true);
p.addLast("ssl", new SslHandler(engine));
}
*/
p.addLast("codec", new HttpClientCodec());
// Remove the following line if you don't want automatic content decompression.
// p.addLast("inflater", new HttpContentDecompressor());
// Uncomment the following line if you don't want to handle HttpChunks.
//p.addLast("aggregator", new HttpObjectAggregator(1048576));
p.addLast("handler", new NettyClientHandler());
}
}
public类NettyClientInitializer扩展了ChannelInitializer{
私有最终布尔ssl;
公共NetCyclientInitializer(布尔ssl){
this.ssl=ssl;
}
@凌驾
public void initChannel(SocketChannel ch)引发异常{
//创建默认管道实现。
ChannelPipeline p=通道管道();
p、 addLast(“log”,新的LoggingHandler(LogLevel.INFO));
//如有必要,启用HTTPS。
/*
如果(ssl){
冷弯发动机=
SecureChatsLContextFactory.getClientContext().CreateSLengine();
engine.setUseClientMode(真);
p、 addLast(“ssl”,新的SslHandler(引擎));
}
*/
p、 addLast(“codec”,新的HttpClientCodec());
//如果不希望自动内容解压缩,请删除以下行。
//p.addLast(“充气机”,新的HttpContentDecompressor());
//如果不想处理HttpChunks,请取消注释以下行。
//p、 addLast(“聚合器”,新的HttpObjectAggregator(1048576));
p、 addLast(“handler”,新的NettyClientHandler());
}
}
处理程序代码:
public class NettyClientHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpResponse) {
HttpResponse response = (HttpResponse) msg;
System.out.println("STATUS: " + response.getStatus());
System.out.println("VERSION: " + response.getProtocolVersion());
System.out.println();
if (!response.headers().isEmpty()) {
for (String name: response.headers().names()) {
for (String value: response.headers().getAll(name)) {
System.out.println("HEADER: " + name + " = " + value);
}
}
System.out.println();
}
if (HttpHeaders.isTransferEncodingChunked(response)) {
System.out.println("CHUNKED CONTENT {");
} else {
System.out.println("CONTENT {");
}
}
if (msg instanceof HttpContent) {
HttpContent content = (HttpContent) msg;
System.out.print(content.content().toString(CharsetUtil.UTF_8));
System.out.flush();
if (content instanceof LastHttpContent) {
System.out.println("} END OF CONTENT");
}
}
}
@Override
public void exceptionCaught(
ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
公共类NetCyclientHandler扩展了SimpleChannelInboundHandler{
@凌驾
public void channelRead0(ChannelHandlerContext ctx,HttpObject msg)引发异常{
if(HttpResponse的消息实例){
HttpResponse响应=(HttpResponse)消息;
System.out.println(“状态:+response.getStatus());
System.out.println(“版本:”+response.getProtocolVersion());
System.out.println();
如果(!response.headers().isEmpty()){
for(字符串名称:response.headers().names()){
for(字符串值:response.headers().getAll(名称)){
System.out.println(“标题:“+name+”=“+value”);
}
}
System.out.println();
}
if(HttpHeaders.isTransferEncodingChunked(响应)){
System.out.println(“分块内容{”);
}否则{
System.out.println(“内容{”);
}
}
if(HttpContent的消息实例){
HttpContent=(HttpContent)msg;
System.out.print(content.content().toString(CharsetUtil.UTF_8));
System.out.flush();
if(LastHttpContent的内容实例){
System.out.println(“}内容结尾”);
}
}
}
@凌驾
公共无效例外情况(
ChannelHandlerContext ctx,可丢弃原因)引发异常{
cause.printStackTrace();
ctx.close();
}
}
在控制台中,我可以看到正在写入请求,但在刷新请求之后,通道将处于非活动状态,然后取消注册
原因可能是我的查询参数未被发送或json问题,或者我的代码中缺少了什么?问题可能在于您正在连接端口443上的服务器
int port = 443;
...
Channel ch = b.connect(host, port).sync().channel();
但是您的NetCyclientInitializer不支持SSL(它在管道外被注释),您构建它的时候就好像SSL没有被使用一样
new NettyClientInitializer(false)
如果将端口更改为80,您的代码可以正常工作。现在它给我302状态代码,即“临时移动”…请告诉我在netty中是如何处理的?302是一个有效的HTTP响应,您已使用netty客户端读取该响应。我无法告诉您服务器返回302的原因,但问题不在于netty。这将由您决定(在您的NetCyclientHandler中)如何处理302。如果您想进一步验证,可以使用curl-v从命令行尝试相同的URL,您将看到返回的302。在从浏览器进行测试时,这可能不太明显,因为它将自动遵循重定向。您能用相同的代码告诉我如何立即关闭连接吗当我收到完整的回复时?因为现在需要大约15分钟才能完全关闭连接,根据我的要求,连接非常高。请确保Mitaksh,如果您接受此问题的答案,我将回答您提交的另一个问题。Hi@MitakshGupta您能告诉我如何解决此问题吗。