基於netty的文件上傳下載組件

基於netty的文件上傳下載組件

1.簡介

該組件基於netty3.6.3實現,具備以下功能:文件上傳,文件替換,文件刪除,若是是圖片的話,還能夠生成縮略圖等功能。
使用簡單,只須要引入netty-file-client,便可以實現文件的以上操做。
該組件的代碼結構分爲兩部分,客戶端組件(netty-flie-client)和服務端組件(netty-flie-server)。以下圖所示:git

image.png

 

2.netty-file-client

2.1 概述

客戶端組件主要提供對外訪問服務端組件的接口,提供如下接口:文件上傳,文件替換,文件刪除,若是是圖片的話,還能夠生成縮略圖等功能。代碼結構以下:github

image.png

org.lyx.file.client包是該組件的核心包,FileClient類是對外提供接口的工具類。具備如下方法:bootstrap

  1. uploadFile 文件上傳,對應文件處理句柄類爲:UploadFileClientHandler
  2. deleteFile 刪除服務端文件,對應文件處理句柄類爲:DeleteFileClientHandler
  3. replaceFile 替換服務端文件,對應文件處理句柄類爲:ReplaceFileClientHandler
  4. createThumbPicture 生成縮略圖,對應文件處理句柄類爲:CreateThumbPictureClientHandler

以上全部句柄類的父類均爲UploadFileClientHandler,該類實現了一些共有方法,好比一些公共參數的包裝等。異步

2.2 實現步驟

實現步驟以上傳文件爲例,其餘相似實現。
直接上代碼:工具

/**
     * 文件上傳
     * @param file 須要上傳的文件
     * @param fileName 文件名稱
     * @param thumbMark 是否須要生成縮略圖
     * @return
     * @author:landyChris
     */
    public static String uploadFile(File file, String fileName,
            boolean thumbMark) {
        FileClientPipelineFactory clientPipelineFactory = new FileClientPipelineFactory();
        //輔助類。用於幫助咱們建立NETTY服務
        ClientBootstrap bootstrap = createClientBootstrap(clientPipelineFactory);
        String strThumbMark = Constants.THUMB_MARK_NO;
        if (thumbMark) {
            strThumbMark = Constants.THUMB_MARK_YES;
        }
        //具體處理上傳文件邏輯
        uploadFile(bootstrap, FileClientContainer.getHost(),
                FileClientContainer.getPort(), file, fileName, strThumbMark,
                FileClientContainer.getUserName(),
                FileClientContainer.getPassword());
        Result result = clientPipelineFactory.getResult();
        if ((result != null) && (result.isCode())) {
            return result.getFilePath();
        }
        return null;
    }

具備三個參數,前面幾行代碼都是很一些netty的初始化工做,具體看一個私有方法uploadFile,以下代碼所示:post

private static void uploadFile(ClientBootstrap bootstrap, String host,
            int port, File file, String fileName, String thumbMark,
            String userName, String pwd) {
        //1.構建uri對象
        URI uri = getUri(host, port);
        //2.鏈接netty服務端
        ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,
                port));
        //3.異步獲取Channel對象
        Channel channel = future.awaitUninterruptibly().getChannel();
        if (!future.isSuccess()) {
            future.getCause().printStackTrace();
            bootstrap.releaseExternalResources();
            return;
        }
        //4.初始化文件上傳句柄對象
        WrapFileClientHandler handler = new UploadFileClientHandler(host, uri,
                file, fileName, thumbMark, userName, pwd);
        //5.獲取Request對象
        HttpRequest request = handler.getRequest();
        //6.獲取Http數據處理工廠
        HttpDataFactory factory = getHttpDataFactory();
        //7.進行數據的包裝處理,主要是進行上傳文件所須要的參數的設置,此時調用的句柄是具體的UploadFileClientHandler對象
        HttpPostRequestEncoder bodyRequestEncoder = handler
                .wrapRequestData(factory);
        //8.把request寫到管道中,傳輸給服務端
        channel.write(request);
        //9.作一些關閉資源的動做
        if (bodyRequestEncoder.isChunked()) {
            channel.write(bodyRequestEncoder).awaitUninterruptibly();
        }
        bodyRequestEncoder.cleanFiles();
        channel.getCloseFuture().awaitUninterruptibly();
        bootstrap.releaseExternalResources();
        factory.cleanAllHttpDatas();
    }

主要有如下實現步驟:spa

  1. 構建uri對象
  2. 鏈接netty服務端
  3. 異步獲取Channel對象
  4. 初始化文件上傳句柄對象
  5. 獲取Request對象
  6. 獲取Http數據處理工廠
  7. 進行數據的包裝處理,主要是進行上傳文件所須要的參數的設置,此時調用的句柄是具體的UploadFileClientHandler對象
  8. 把request寫到管道中,傳輸給服務端
  9. 作一些關閉資源的動做
    具體細節實現請參考github上的代碼。若是各位讀者喜歡的話,能夠加個star哈。

3.netty-file-server

3.1 概述

服務端組件實現功能也是跟客戶端一致,具備如下功能:文件上傳,文件替換,文件刪除,若是是圖片的話,還能夠生成縮略圖等功能。代碼結構以下圖所示:.net

image.png

org.lyx.file.server包是該組件的核心包。具體的處理句柄類有如下幾個:netty

  1. 文件上傳:UploadFileServerHandler
  2. 刪除文件:DeleteFileServerHandler
  3. 替換文件:ReplaceFileServerHandler
  4. 生成縮略圖:CreateThumbPictureServerHandler

以上因此句柄類的接口均爲FileServerProcessor,而且繼承了抽象類AbstractFileServerHandler。code

3.2 實現步驟

具體實現步驟仍是以文件上傳爲例。
首先org.lyx.file.server.support.FileServerHandler類會持續監聽客戶端的請求,若是是文件處理動做,則會進入messageReceived方法進行相應的處理邏輯。該類定義瞭如下成員變量:

//http請求
    private HttpRequest request;
    //是否須要斷點續傳做業
    private boolean readingChunks;
    //接收到的文件內容
    private final StringBuffer responseContent = new StringBuffer();
    //解析收到的文件
    private static final HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); //16384L
    //post請求的解碼類,它負責把字節解碼成Http請求。
    private HttpPostRequestDecoder decoder;
    //請求參數
    private RequestParam requestParams = new RequestParam();

該方法實現中,若是文件大小小於chunked的最小值,則直接進行文件上傳操做。不然,須要進行分塊處理。而後進行文件上傳操做。
文件大小小於1k的操做:

image.png

須要分塊處理操做:


image.png

以上操做主要有兩個注意點:

  1. 請求參數的解析工做(根據HttpDataType進行相應參數的賦值操做)
  2. 根據解析的參數進行相應的文件處理操做(根據文件操做類型,選擇相應的處理句柄進行文件處理)

以上具體實現請參見github實現。

代碼地址:https://github.com/landy8530/netty-file-parent

原文地址:http://www.jianshu.com/p/bf85de3e102e 來自簡書,做者:landy8530.

更多資訊請閱讀:http://www.jianshu.com/u/36a7d3a994ac

做者公衆號:螞蟻與咖啡的故事

公衆號二維碼:

螞蟻與咖啡的故事

相關文章
相關標籤/搜索