利用Netty中提供的HttpChunk簡單實現文件傳輸

jopen 9年前發布 | 2K 次閱讀 Java Netty

利用Netty中提供的HttpChunk簡單實現文件傳輸。 服務端基本和Netty官方文檔中的example:http--file一樣。

HttpClient.java

public class HttpClient {

private ClientBootstrap bootstrap;
private String host="localhost";
private Channel channel;
private boolean futureSuccess;
private int port=8080;

public HttpClient() {
}

public ChannelFuture connect() {
    bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors
            .newCachedThreadPool()));
    HttpResponseHandler clientHandler = new HttpResponseHandler();
    bootstrap.setPipelineFactory(new HttpClientPipelineFactory(clientHandler));

    bootstrap.setOption("tcpNoDelay", true);
    bootstrap.setOption("keepAlive", true);

    return bootstrap.connect(new InetSocketAddress(host,port));
}

public boolean checkFutureState(ChannelFuture channelFuture) {
    // Wait until the connection attempt succeeds or fails.
    channel = channelFuture.awaitUninterruptibly().getChannel();
    channelFuture.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture connectFuture) throws Exception {
            if (!connectFuture.isSuccess()) {
                connectFuture.getCause().printStackTrace();
                // connectFuture.getChannel().close();
                // bootstrap.releaseExternalResources();
                futureSuccess = false;
            } else {
                futureSuccess = true;
            }
        }
    });
    return futureSuccess;
}

public ChannelFuture write(HttpRequest request) {
    return channel.write(request);
}

public void Close() {
    // Close the connection. Make sure the close operation ends because
    // all I/O operations are asynchronous in Netty.
    channel.close().awaitUninterruptibly();
    // Shut down all thread pools to exit.
    bootstrap.releaseExternalResources();
}

}</pre>

HttpClientPipelineFactory.java

public class HttpClientPipelineFactory implements ChannelPipelineFactory {
private final HttpResponseHandler handler;

public HttpClientPipelineFactory(HttpResponseHandler handler) {  
    this.handler = handler;  
}  

public ChannelPipeline getPipeline() throws Exception {  
    ChannelPipeline pipeline = pipeline();  

    pipeline.addLast("decoder", new HttpResponseDecoder());  
    //pipeline.addLast("aggregator", new HttpChunkAggregator(6048576));  
    pipeline.addLast("encoder", new HttpRequestEncoder());  
    pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());  
    pipeline.addLast("handler", handler);  

    return pipeline;  
}  

} </pre>

HttpResponseHandler.java

@ChannelPipelineCoverage("one")
public class HttpResponseHandler extends SimpleChannelUpstreamHandler {
private volatile boolean readingChunks;
private File downloadFile;
private FileOutputStream fOutputStream = null;

@Override  
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {  
    if (e.getMessage() instanceof HttpResponse) {  
        DefaultHttpResponse httpResponse = (DefaultHttpResponse) e.getMessage();  
        String fileName = httpResponse.getHeader("Content-Disposition").substring(20);  
        downloadFile = new File(System.getProperty("user.dir") + File.separator + "download" + fileName);  
        readingChunks = httpResponse.isChunked();  
    } else {  
        HttpChunk httpChunk = (HttpChunk) e.getMessage();  
        if (!httpChunk.isLast()) {  
            ChannelBuffer buffer = httpChunk.getContent();  
            if (fOutputStream == null) {  
                fOutputStream = new FileOutputStream(downloadFile);  
            }  
            while (buffer.readable()) {  
                byte[] dst = new byte[buffer.readableBytes()];  
                buffer.readBytes(dst);  
                fOutputStream.write(dst);  
            }  
        } else {  
            readingChunks = false;  
        }  
        fOutputStream.flush();  
    }  
    if (!readingChunks) {  
        fOutputStream.close();  
    }  
}  

@Override  
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {  
    System.out.println(e.getCause());  
}  

} </pre>

ClientMain.java

public class ClientMain {  
    public static void main(String[] args) {  
        HttpClient httpClient=new HttpClient();  
        ChannelFuture connectFuture=httpClient.connect();  
        if (httpClient.checkFutureState(connectFuture)) {  
            System.out.println("connect ok");  
            HttpRequest request=new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "thunder.zip");  
//          HttpRequest request=new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "thunder.java");  
            ChannelFuture writeFuture= httpClient.write(request);  
            if (httpClient.checkFutureState(writeFuture)) {  
                System.out.println("write ok");  
            }  
        }  
    }  
}  

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!