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

1.簡介

該組件基于netty3.6.3實現(xiàn),具有如下功能:文件上傳,文件替換,文件刪除,如果是圖片的話,還可以生成縮略圖等功能。
使用簡單,只需要引入netty-file-client,即可以實現(xiàn)文件的以上操作。
該組件的代碼結(jié)構(gòu)分為兩部分,客戶端組件(netty-flie-client)和服務(wù)端組件(netty-flie-server)。如下圖所示:

image.png

2.netty-file-client

2.1 概述

客戶端組件主要提供對外訪問服務(wù)端組件的接口,提供以下接口:文件上傳,文件替換,文件刪除,如果是圖片的話,還可以生成縮略圖等功能。代碼結(jié)構(gòu)如下:

image.png

org.lyx.file.client包是該組件的核心包,F(xiàn)ileClient類是對外提供接口的工具類。具有以下方法:

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

以上所有句柄類的父類均為UploadFileClientHandler,該類實現(xiàn)了一些共有方法,比如一些公共參數(shù)的包裝等。

2.2 實現(xiàn)步驟

實現(xiàn)步驟以上傳文件為例,其他類似實現(xiàn)。
直接上代碼:

/**
     * 文件上傳
     * @param file 需要上傳的文件
     * @param fileName 文件名稱
     * @param thumbMark 是否需要生成縮略圖
     * @return
     * @author:landyChris
     */
    public static String uploadFile(File file, String fileName,
            boolean thumbMark) {
        FileClientPipelineFactory clientPipelineFactory = new FileClientPipelineFactory();
        //輔助類。用于幫助我們創(chuàng)建NETTY服務(wù)
        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;
    }

具有三個參數(shù),前面幾行代碼都是很一些netty的初始化工作,具體看一個私有方法uploadFile,如下代碼所示:

private static void uploadFile(ClientBootstrap bootstrap, String host,
            int port, File file, String fileName, String thumbMark,
            String userName, String pwd) {
        //1.構(gòu)建uri對象
        URI uri = getUri(host, port);
        //2.連接netty服務(wù)端
        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數(shù)據(jù)處理工廠
        HttpDataFactory factory = getHttpDataFactory();
        //7.進(jìn)行數(shù)據(jù)的包裝處理,主要是進(jìn)行上傳文件所需要的參數(shù)的設(shè)置,此時調(diào)用的句柄是具體的UploadFileClientHandler對象
        HttpPostRequestEncoder bodyRequestEncoder = handler
                .wrapRequestData(factory);
        //8.把request寫到管道中,傳輸給服務(wù)端
        channel.write(request);
        //9.做一些關(guān)閉資源的動作
        if (bodyRequestEncoder.isChunked()) {
            channel.write(bodyRequestEncoder).awaitUninterruptibly();
        }
        bodyRequestEncoder.cleanFiles();
        channel.getCloseFuture().awaitUninterruptibly();
        bootstrap.releaseExternalResources();
        factory.cleanAllHttpDatas();
    }

主要有以下實現(xiàn)步驟:

  1. 構(gòu)建uri對象
  2. 連接netty服務(wù)端
  3. 異步獲取Channel對象
  4. 初始化文件上傳句柄對象
  5. 獲取Request對象
  6. 獲取Http數(shù)據(jù)處理工廠
  7. 進(jìn)行數(shù)據(jù)的包裝處理,主要是進(jìn)行上傳文件所需要的參數(shù)的設(shè)置,此時調(diào)用的句柄是具體的UploadFileClientHandler對象
  8. 把request寫到管道中,傳輸給服務(wù)端
  9. 做一些關(guān)閉資源的動作
    具體細(xì)節(jié)實現(xiàn)請參考github上的代碼。如果各位讀者喜歡的話,可以加個star哈。

3.netty-file-server

3.1 概述

服務(wù)端組件實現(xiàn)功能也是跟客戶端一致,具有以下功能:文件上傳,文件替換,文件刪除,如果是圖片的話,還可以生成縮略圖等功能。代碼結(jié)構(gòu)如下圖所示:

image.png

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

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

以上所以句柄類的接口均為FileServerProcessor,并且繼承了抽象類AbstractFileServerHandler。

3.2 實現(xiàn)步驟

具體實現(xiàn)步驟還是以文件上傳為例。
首先org.lyx.file.server.support.FileServerHandler類會持續(xù)監(jiān)聽客戶端的請求,如果是文件處理動作,則會進(jìn)入messageReceived方法進(jìn)行相應(yīng)的處理邏輯。該類定義了以下成員變量:

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

該方法實現(xiàn)中,如果文件大小小于chunked的最小值,則直接進(jìn)行文件上傳操作。否則,需要進(jìn)行分塊處理。然后進(jìn)行文件上傳操作。
文件大小小于1k的操作:

image.png

需要分塊處理操作:


image.png

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

  1. 請求參數(shù)的解析工作(根據(jù)HttpDataType進(jìn)行相應(yīng)參數(shù)的賦值操作)
  2. 根據(jù)解析的參數(shù)進(jìn)行相應(yīng)的文件處理操作(根據(jù)文件操作類型,選擇相應(yīng)的處理句柄進(jìn)行文件處理)

以上具體實現(xiàn)請參見github實現(xiàn)。

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,881評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,105評論 25 708
  • 本文包括:1、文件上傳概述2、利用 Commons-fileupload 組件實現(xiàn)文件上傳3、核心API——Dis...
    廖少少閱讀 12,587評論 5 91
  • 前言:人總是在百無聊賴中虛度時光,或在水深火熱中自我掙扎與自我救贖,時常想起每一個鮮活的生命都是由各種各樣的生活經(jīng)...
    greencountry閱讀 230評論 0 0
  • 目錄 01--它與它的影 02--賈科梅蒂 03--杜尚 01 它與它的影 被構(gòu)思,被創(chuàng)造,被安置 被圍觀,被評...
    蘇鐵的年輪閱讀 246評論 0 1