Java 使用 Netty 的 HTTP 请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20041238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTTP Request using Netty
提问by Mitaksh Gupta
I have just started netty and I am really disappointed with the documentation present on their website.
我刚刚开始使用 netty,我对他们网站上的文档感到非常失望。
I am trying to connect to an URL using Netty.. I took the time client example from their website and changed it as per my requirement..
我正在尝试使用 Netty 连接到一个 URL。我从他们的网站上获取了时间客户端示例,并根据我的要求对其进行了更改。
Code :
代码 :
public class NettyClient {
public static void main(String[] args) throws Exception {
String host = "myUrl.com/v1/parma?param1=value";
int port = 443;
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ClientHandler());
ch.pipeline().addLast("encoder", new HttpRequestEncoder());
}
});
// Start the client.
ChannelFuture f = b.connect(host, port).sync();
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
}
But the problem is that that it expects only the url without the query parameters.. How can I pass query parameters with the URL? and please provide me some link of a good documentation for Netty 4..
但问题是它只需要 url 而没有查询参数..如何通过 URL 传递查询参数?请为我提供一些 Netty 4 良好文档的链接。
EDIT
编辑
Client code after referring the example mentioned in the answer :
参考答案中提到的示例后的客户端代码:
URI uri = new URI("myUrl.com/v1/parma?param1=value");
String scheme = uri.getScheme() == null? "http" : uri.getScheme();
String host = "myUrl.com";
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(ssl));
// 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, uri.getRawPath());
request.headers().set(HttpHeaders.Names.HOST, host);
request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
//request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);
/*// Set some example cookies.
request.headers().set(
HttpHeaders.Names.COOKIE,
ClientCookieEncoder.encode(
new DefaultCookie("my-cookie", "foo"),
new DefaultCookie("another-cookie", "bar")));
*/
// 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();
}
handler code :
处理程序代码:
public class ClientHandler 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();
}
}
initializer code :
初始化代码:
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 ClientHandler());
}
}
回答by Tarmo R
Your code only handles the low-level connection at the moment. Indeed at this level only the hostname and port can be used.
您的代码目前仅处理低级连接。实际上,在此级别只能使用主机名和端口。
For the HTTP request You have to construct an HttpRequest
object and send it over the channel. In this request object You define the query parameters and all such things.
对于 HTTP 请求,您必须构造一个HttpRequest
对象并通过通道发送它。在这个请求对象中你定义了查询参数和所有这些东西。
There is a bunch of example code about HTTP client functionality on Netty website - have a a look!
Netty 网站上有一堆关于 HTTP 客户端功能的示例代码 -看看!
回答by Walt Corey
In this example the problem lies with the constructor for the DefaultHttpRequest parameter of uri.getRawPath(). The invocation of this method does NOT return the query parameters. It works in this case as there were no query parameters in the Snoop example. By substituting uri.toASCIIString() returns the encoded uri complete with the query parameters. To prove this to yourself, rather than having a method invocation within a method invocation (a bad idea for just this reason, add the statement
在这个例子中,问题在于 uri.getRawPath() 的 DefaultHttpRequest 参数的构造函数。调用此方法不返回查询参数。它在这种情况下有效,因为在 Snoop 示例中没有查询参数。通过替换 uri.toASCIIString() 返回带有查询参数的编码 uri。为了向自己证明这一点,而不是在方法调用中进行方法调用(出于这个原因,这是一个坏主意,添加语句
String url = uri.getRawPath();
and look at the string url.
并查看字符串 url。
I had the exact same problem. I've done this natively in servlets for years but now was trying to do it in a Netty app.
我有同样的问题。多年来,我一直在 servlet 中本地完成此操作,但现在尝试在 Netty 应用程序中执行此操作。
Consequently the new code would be:
因此,新代码将是:
String path = uri.toASCIIString();
// Prepare the HTTP request.
HttpRequest request = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.GET, path);
回答by MrBigglesworth
When you build the request, you need to add the query to the path. Instead of
构建请求时,需要将查询添加到路径中。代替
uri.getRawPath()
uri.getRawPath()
use
用
uri.getRawPath() + "?" + uri.getRawQuery()
uri.getRawPath() + "?" + uri.getRawQuery()