如何在 Java NIO Http Server 中处理多部分表单数据

How can I handle multipart form data in Java NIO Htttp Server

我已经使用 Java NIO 实现了非阻塞 Http 服务器。它适用于 x-www-form-urlencoded POST 请求。但是当我尝试使用大文件进行 HTTP 多部分请求时,它不起作用。在那种情况下,服务器无法响应 http 客户端。这是我的 NIO 服务器源代码。

public class TCPServer {

    public static void main(String[] args) {
       TCPServer server = new TCPServer();
       server.listen();
    }

    public void listen() {

        try {

             Selector selector = Selector.open();

             ServerSocketChannel serverSocketChannel = ServerSocketChannel
                .open();

             InetSocketAddress serverAddress = new InetSocketAddress(8080);

             serverSocketChannel.bind(serverAddress);

             serverSocketChannel.configureBlocking(false);

             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

             while (true) {

                  selector.select();

                  Set<SelectionKey> selectionKeys = selector.selectedKeys();
                  Iterator<SelectionKey> iterator =  selectionKeys.iterator();

                  while (iterator.hasNext()) {
                      SelectionKey key = iterator.next();

                      if (key.isAcceptable()) {
                          SocketChannel clientSocketChannel =  serverSocketChannel.accept();

                       clientSocketChannel.configureBlocking(false);

                       clientSocketChannel.register(selector,
                            SelectionKey.OP_READ);

                      } else if (key.isReadable()) {
                           SocketChannel clientSocketChannel = null;
                           try {
                               clientSocketChannel = (SocketChannel) key.channel();

                               ByteBuffer clientBuffer = ByteBuffer.allocate(1024);

                               StringBuilder requestStringBuilder = new StringBuilder();

                                int bytesRead = clientSocketChannel
                                .read(clientBuffer); 

                                while (bytesRead > 0) {

                                     clientBuffer.flip();

                                     String result = new String(clientBuffer.array());
                                     requestStringBuilder.append(result);

                                     clientBuffer.compact();

                                     bytesRead = clientSocketChannel.read(clientBuffer);

                                }

                                System.out.println("request-----");
                                System.out
                                  .println(requestStringBuilder.toString());

                                clientSocketChannel.write(ByteBuffer
                                  .wrap("reply from server".getBytes()));

                                clientSocketChannel.register(selector,
                                SelectionKey.OP_WRITE);
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                        clientSocketChannel.close();
                    }

                } else if (key.isWritable()) {
                    SocketChannel clientSocketChannel = null;
                    try {
                        clientSocketChannel = (SocketChannel) key.channel();
                        clientSocketChannel.close();
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                        clientSocketChannel.close();
                    }
                }
                iterator.remove();

            }
          }
        }catch (Exception e) {
             System.err.println(e.getMessage());
        }

    }

 }

有没有其他方法可以在 Java NIO 非阻塞 server.How 中处理 HTTP 多部分请求?我可以解决这个问题吗?谢谢

这类似于另一个问题:Servlet 3.1 - Multipart async processing,但我会在这里回答,因为该解决方案也适用于普通非阻塞 IO。

Synchronoss Technologies 最近开源了一个非阻塞 HTTP 多部分解析器 here

当您的非阻塞服务器接收数据时,您只需将传入的字节传递给 NioMultipartParser。解析器将为收到的每个部分回调您的代码。

免责声明:我在 Synchronoss Technologies 工作。我们为 Servlet 3.1 编写了这个,但它也应该有意在常规的非阻塞应用程序中工作,所以希望其他人会发现这个库有用。