java - 在 Netty 中处理 Http 状态码 302 Moved Temporarily

标签 java redirect httprequest netty http-status-code-302

我收到我对我的 URL 发出的 http 请求的 302 状态代码。我希望它由我的 netty 代码处理。

我的客户端代码:

      public static void main(String[] args) throws Exception {
           URI uri = new URI("http://myurl.mydomain.com/v1/v2?param1=value1&param2=value2");           
           String host = uri.getHost();
            int port = 80;

         // Configure the client.
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group)
                 .channel(NioSocketChannel.class)
                 .handler(new NettyClientInitializer());
                // 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.toString());
                request.headers().set(HttpHeaders.Names.HOST, host);
                request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);  
                request.headers().set(HttpHeaders.Names.CACHE_CONTROL, HttpHeaders.Values.NO_CACHE);

                /*// 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();
            }
      }

我的处理程序代码:

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();
    }


}

我的初始化代码:

public class NettyClientInitializer extends ChannelInitializer<SocketChannel> {


    @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());

    }
}

我提到这个链接有类似的问题: redirect - handling http 302 moved temporarily using netty

但是这里的代码使用的是 3.x 版本的库,而且这个问题目前还没有答案。

我正在使用 Netty 4.0.12 库..

请告诉我如何使用 Netty 处理此问题

最佳答案

您可以修改您的 NettyClientHandler 以检查 302 重定向,并打开一个新连接来处理重定向的 HTML 内容。

NettyClientHandler 所做的更改:

//We know this is a redirect...
            if(response.getStatus().code() == HttpResponseStatus.FOUND.code()){//When its a 302...

                if(response.headers().names().contains("Location"))
                {
                    System.out.println("We have a redirect...");
                    //Now we will do the process over to get the actual content...
                    Main.main(new String[]{response.headers().get("Location")});
                }
            }

main()为例处理重定向内容的改动:

String urlPlace = "http://initial.com";

        if(args != null && args.length > 0)
        {
            urlPlace = args[0];
        }

        URI uri = new URI(urlPlace);
        String host = uri.getHost();
        int port = uri.getPort();
        if(port == -1)
        {
            port = 80;
        }

当我们收到 HTTP 状态代码 302 时,“服务器”有责任为新的 URL 位置设置 Location header ,以便客户端处理适本地。

参见 Wikipedia 302

关于java - 在 Netty 中处理 Http 状态码 302 Moved Temporarily,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20212505/

相关文章:

spring - 为什么使用 HttpServletRequest 向浏览器发送响应?

javascript - 在 Firefox 扩展中重定向请求(nsiHttpChannel?)

java - 为什么ProGuard输出的JAR文件中没有class文件?

laravel - 抱歉,无法找到您要查找的页面。拉拉维尔

java - 如何使用传输实用程序从 s3 下载特定版本文件

redirect - 如何对所有以数字开头的页面进行 htaccess 通配符重定向

node.js - 从 Node.JS 服务器重定向到路由不会呈现下一页

php - 将带有 formData 的数据发送到 mysql

java - IntelliJ IDEA 13 调试器不会在 Maven 项目的 Java 断点处停止

java - 使用 MySQL 在 Hibernate Java 中获取两个日期之间的数据?