netty上传文件例子


只需一次请求就可以上传文件成功;如果文件内容大于1024个字节,需多次分片上传,用到httpchunk,分片处理机制(netty本身自带)。
一次处理不玩,分多次上传。
*/public class UploadHandler {
    private static final long serialVersionUID = 1092232169163288262L;
    protected static String fileUploadPath = "";
    protected static String fileUploadUrl =  "";
    protected static String imageUploadPath = "";
    protected static String imageUploadUrl = "";

    private boolean          readingChunks = false;
    private FileOutputStream fOutputStream = null;
    private boolean          isReadSuccess = true;    
    
    public boolean upload(ChannelHandlerContext ctx, MessageEvent e) throws IOException{
        boolean isUploadFinished=false;
        Channel channel = e.getChannel();
            if (e.getMessage().getClass() == DefaultHttpRequest.class){ //第一次请求上传,无论文件大小,都走该请求
                DefaultHttpRequest request = (DefaultHttpRequest) e.getMessage();  
                if( request.isChunked() ){//netty自己分析文件大小,是否需要分片上传文件。
                    readingChunks = true;
                }else{
                    ChannelBuffer buffer = request.getContent();
                    readFileContent(buffer);
                    isUploadFinished=true;
                }
            } else {  //netty分片上传的实现
                HttpChunk httpChunk = (HttpChunk) e.getMessage();  
                if (!httpChunk.isLast()){  
                    ChannelBuffer buffer = httpChunk.getContent();  
                    readFileContent(buffer);
                } else {  
                    readingChunks = false;  
                    isUploadFinished=true;
                }  
            }  
        return isUploadFinished;
    }
    
    private boolean readFileContent( ChannelBuffer buffer ){
        try{
            if (fOutputStream == null){  
                ByteArrayOutputStream buf = new ByteArrayOutputStream();
                while( buffer.readable() ){
                    byte b = buffer.readByte();
                    buf.write(b);
                    if( b == '\n' && new String(buf.toByteArray()).endsWith("\r\n\r\n") ) break;
                }
                String content = buf.toString("utf8");
                FileItem fileItem = FileItem.parseFileItem(content);
                String name = fileItem.getFieldName();
                if (!name.equals("file")) return false;
                String fileName = fileItem.getFilename();
                if (fileName.indexOf("\\") > -1) {
                    fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                }
                File file = new File("D://"+fileName);
                fOutputStream = new FileOutputStream(file);
            }  
            while (buffer.readable()){  
                byte[] dst = new byte[buffer.readableBytes()];  
                buffer.readBytes(dst);  
                fOutputStream.write(dst);
            }
            fOutputStream.flush();
            return true;
        }catch(Exception e){
            isReadSuccess=false;
            return false;
        }
    }    

}

//用于封装请求的头信息,获取文件名,文件类型等信息。
class FileItem{
    private String filename;
    private String mimeType;
    private String fieldName;
    
    public FileItem( String filename , String mimeType , String fieldName ) {
        this.filename = filename;
        this.mimeType = mimeType;
        this.fieldName      = fieldName;
    }
    
    public static FileItem parseFileItem( String content ){
        if( content == null ) return null;
        String filename = null;
        String mimeType = null;
        String name        = null;
        String[] rows = content.split("\r\n");
        for( String row : rows ){
            int idx = row.indexOf(":");
            if( idx > 0 ){
                String key = row.substring(0,idx);
                if("Content-Disposition".equals(key)){
                    String val = row.substring(idx+1);
                    String[] items = val.split(";");
                    for( String item : items ){
                        String[] kv = item.split("=");
                        String k = kv[0].trim();
                        if( "name".equals(k) ){
                            name = kv[1].replace("\"", "");
                        }else if( "filename".equals(k) ){
                            filename = kv[1].replace("\"", "");
                        }
                    }
                }else if( "Content-Type".equals(key) ){
                    String val = row.substring(idx+1);
                    mimeType = val.trim();
                }
            }
        }
        return new FileItem(filename, mimeType, name);
    }
    
    public String getFilename() {
        return filename;
    }

    public String getMimeType() {
        return mimeType;
    }

    public String getFieldName() {
        return fieldName;
    }
    
    @Override
    public String toString() {
        return String.format("name=%s  mimetype=%s  filename=%s", this.fieldName,this.mimeType,this.filename);
    }
}

转载于:https://my.oschina.net/aicoding/blog/178733

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值