netty上传文件例子

jopen 10年前

/由于netty本身的性能需求,每次传输的字节数最大为1024个字节,所以如果文件内容小于1024个字节,
只需一次请求就可以上传文件成功;如果文件内容大于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;          }      }        } </pre>

//用于封装请求的头信息,获取文件名,文件类型等信息。
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);      }  }