如何从NETTY 4的POST请求获取文件数据?

4

我可以向服务器发送带有jpg文件的POST请求。

POST /formpostmultipart HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 621551
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2031.2 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryY1m4URqQ5ydALOrQ
Referer: http://localhost:8080/upload
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4

我该怎么做才能从这个请求中获取文件并保存到磁盘上呢?

注:很抱歉我的英文不太好。

2个回答

4
我用HttpPostRequestDecoder解决了这个问题。例如:
if (request.getMethod().equals(HttpMethod.POST)) {
                    decoder = new HttpPostRequestDecoder(dataFactory, request);
                    decoder.setDiscardThreshold(0);
if (decoder != null) {
        if (msg instanceof HttpContent) {
            HttpContent chunk = (HttpContent) msg;
            decoder.offer(chunk);
            readChunk(channelHandlerContext);
            if (chunk instanceof LastHttpContent) {
                resetPostRequestDecoder();
            }
        }
    }
private void readChunk(ChannelHandlerContext ctx) throws IOException {
    while (decoder.hasNext()) {
        InterfaceHttpData data = decoder.next();
        if (data != null) {
            try {
                switch (data.getHttpDataType()) {
                    case Attribute:
                        break;
                    case FileUpload:    
                        FileUpload fileUpload = (FileUpload) data;
                        File file = new File("C:\\test\\" + fileUpload.getName);
                        if (!file.exists()) {
                            file.createNewFile();
                        }
                        try (FileChannel inputChannel = new FileInputStream(fileUpload.getFile()).getChannel(); FileChannel outputChannel = new FileOutputStream(file).getChannel()) {
                            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
                            sendSimpleResponse(ctx,CREATED,"file name: " +file.getAbsolutePath());
                        }
                        break;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                data.release();
            }
        }
    }
}

private void resetPostRequestDecoder() {
    request = null;
    decoder.destroy();
    decoder = null;
}

1
你的管道中有什么处理程序?我遇到了同样的问题,但我总是得到 HTTPRequest 而不是 HTTPContent。 - Subash Chaturanga

2
以下是使用Netty 4.1.3.Final的示例。其中一些代码片段来自于mechanikos的答案。
管道如下:
pipeline.addLast(new HttpRequestDecoder());
pipeline.addLast(new HttpResponseEncoder());
pipeline.addLast(new MyHttUploadServerHandler());

通道读取处理:

protected void channelRead0(final ChannelHandlerContext ctx, final HttpObject httpObject)
    throws Exception {
    if (httpObject instanceof HttpRequest) {
      httpRequest = (HttpRequest) httpObject;
      final URI uri = new URI(httpRequest.uri());

      System.out.println("Got URI " + uri);
      if (httpRequest.method() == POST) {
        httpDecoder = new HttpPostRequestDecoder(factory, httpRequest);
        httpDecoder.setDiscardThreshold(0);
      } else {
        sendResponse(ctx, METHOD_NOT_ALLOWED, null);
      }
    }
    if (httpDecoder != null) {
      if (httpObject instanceof HttpContent) {
        final HttpContent chunk = (HttpContent) httpObject;
        httpDecoder.offer(chunk);
        readChunk(ctx);

        if (chunk instanceof LastHttpContent) {
          resetPostRequestDecoder();
        }
      }
    }
  }

  private void readChunk(ChannelHandlerContext ctx) throws IOException {
    while (httpDecoder.hasNext()) {
      InterfaceHttpData data = httpDecoder.next();
      if (data != null) {
        try {
          switch (data.getHttpDataType()) {
            case Attribute:
              break;
            case FileUpload:
              final FileUpload fileUpload = (FileUpload) data;
              final File file = new File(FILE_UPLOAD_LOCN + fileUpload.getFilename());
              if (!file.exists()) {
                file.createNewFile();
              }
              System.out.println("Created file " + file);
              try (FileChannel inputChannel = new FileInputStream(fileUpload.getFile()).getChannel();
                   FileChannel outputChannel = new FileOutputStream(file).getChannel()) {
                outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
                sendResponse(ctx, CREATED, "file name: " + file.getAbsolutePath());
              }
              break;
          }
        } finally {
          data.release();
        }
      }
    }
}

完整代码片段可在此处找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接