該組件基於netty3.6.3實現,具備以下功能:文件上傳,文件替換,文件刪除,若是是圖片的話,還能夠生成縮略圖等功能。
使用簡單,只須要引入netty-file-client,便可以實現文件的以上操做。
該組件的代碼結構分爲兩部分,客戶端組件(netty-flie-client)和服務端組件(netty-flie-server)。以下圖所示:git
客戶端組件主要提供對外訪問服務端組件的接口,提供如下接口:文件上傳,文件替換,文件刪除,若是是圖片的話,還能夠生成縮略圖等功能。代碼結構以下:github
org.lyx.file.client包是該組件的核心包,FileClient類是對外提供接口的工具類。具備如下方法:bootstrap
以上全部句柄類的父類均爲UploadFileClientHandler,該類實現了一些共有方法,好比一些公共參數的包裝等。異步
實現步驟以上傳文件爲例,其餘相似實現。
直接上代碼:工具
/** * 文件上傳 * @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
服務端組件實現功能也是跟客戶端一致,具備如下功能:文件上傳,文件替換,文件刪除,若是是圖片的話,還能夠生成縮略圖等功能。代碼結構以下圖所示:.net
org.lyx.file.server包是該組件的核心包。具體的處理句柄類有如下幾個:netty
以上因此句柄類的接口均爲FileServerProcessor,而且繼承了抽象類AbstractFileServerHandler。code
具體實現步驟仍是以文件上傳爲例。
首先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的操做:
須要分塊處理操做:
以上操做主要有兩個注意點:
以上具體實現請參見github實現。
代碼地址:https://github.com/landy8530/netty-file-parent
原文地址:http://www.jianshu.com/p/bf85de3e102e 來自簡書,做者:landy8530.
更多資訊請閱讀:http://www.jianshu.com/u/36a7d3a994ac
做者公衆號:螞蟻與咖啡的故事
公衆號二維碼: