一、概述
這篇文章描述如何通過Netty提供的工具,處理http multipart文件上傳。
二、ChannelPipeline設置
2.1 netty http 服務端
//解碼http協議爲HttpObject對象
pipeline.addLast(new HttpRequestDecoder());
//編碼HttpResponse對象爲字節流
pipeline.addLast(new HttpResponseEncoder());
//聚合Http請求或響應,否則你會收到HttpMessage,HttpContent等對象
//有了這個Handler,只會收到FullHttpRequest類型的對象
pipeline.addLast(new HttpObjectAggregator(8192));
//如果客戶端設置了Accept-Encoding頭,通過gzip等方式壓縮報文體
pipeline.addLast(new HttpContentCompressor());
//你自己的業務處理器
pipeline.addLast(new HttpRequestHandler());
2.2 netty http客戶端
p.addLast(new HttpRequestEncoder());
p.addLast(new HttpResponseDecoder());
p.addLast(new HttpObjectAggregator(8192));
//no need if we don't set Accept-Encoding header
p.addLast(new HttpContentDecompressor());
p.addLast(new HttpResponseHandler());
三、netty客戶端發送multipart/form-data請求
DefaultFullHttpRequest multipartRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,
"/upload");
//通過這個工具構造multipart請求格式
HttpPostRequestEncoder encoder = new HttpPostRequestEncoder(multipartRequest, true);
//在報文體中添加一個簡單屬性
encoder.addBodyAttribute("key1", "value1");
//在報文體中添加文件上傳屬性
encoder.addBodyFileUpload("file", new File("/Users/linjingfu/Desktop/today.txt"),
HttpHeaderValues.APPLICATION_OCTET_STREAM.toString(), false);
//發生請求行,以及請求頭內容
HttpRequest requestToBeSend = encoder.finalizeRequest();
System.out.println(requestToBeSend.headers());
client.getChannel().writeAndFlush(requestToBeSend);
//發送多個"chunk",即分段發送多個屬性及文件內容
while (true) {
HttpContent chunk = encoder.readChunk(client.getChannel().alloc());
if (chunk == null) {
break;
}
client.getChannel().writeAndFlush(chunk);
if (encoder instanceof LastHttpContent) {
break;
}
}
四、netty服務端處理multipart請求
//decode multipart data, request爲FullHttpRequest類型
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
while (decoder.hasNext()) {
InterfaceHttpData httpData = decoder.next();
if (httpData instanceof Attribute) {
Attribute attr = (Attribute)httpData;
System.out.println("收到mutlipart屬性:" + attr);
} else if (httpData instanceof FileUpload) {
FileUpload fileUpload = (FileUpload)httpData;
System.out.println("收到multipart文件:" + fileUpload);
//可實際保存文件或做其他事情...
}
}
decoder.destroy();