Vertx简单表单上传

我正在使用vertx简单的表单上传。当我上传单个文件时工作正常。如果表单具有“多个”输入并选择多个文件,则HTTPServerUpload出现错误“响应已被写入(java.lang.IllegalStateException: Response has already been written)”。由于响应在第一个文件的末端处理程序中结束,因此它将为后续文件抛出此错误。有没有其他方式来处理多个文件?

错误的代码,抛出的错误

public class SimpleFormUploadServer extends AbstractVerticle {


    public static void main(String[] args) {
        Runner.runExample(SimpleFormUploadServer.class);
    }

    @Override
    public void start() throws Exception {
        vertx.createHttpServer()
                .requestHandler(req -> {
                    if (req.uri().equals("/")) {
                        // Serve the index page
                        req.response().sendFile("index.html");
                    } else if (req.uri().startsWith("/form")) {
                        req.setExpectMultipart(true);
                        req.uploadHandler(upload -> {
                            upload.exceptionHandler(cause -> {
                                req.response().setChunked(true)
                                        .end("Upload failed");
                            });

                            upload.endHandler(v -> {
                                req.response()
                                        .setChunked(true)
                                        .end("Successfully uploaded to "
                                                + upload.filename());
                            });
                            // FIXME - Potential security exploit! In a real
                            // system you must check this filename
                            // to make sure you're not saving to a place where
                            // you don't want!
                            // Or better still, just use Vert.x-Web which
                            // controls the upload area.
                            upload.streamToFileSystem(upload.filename());
                        });
                    } else {
                        req.response().setStatusCode(404);
                        req.response().end();
                    }
                }).listen(8080);

    }
}

Exception :

SEVERE: Unhandled exception
java.lang.IllegalStateException: Response has already been written
    at io.vertx.core.http.impl.HttpServerResponseImpl.checkWritten(HttpServerResponseImpl.java:561)
    at io.vertx.core.http.impl.HttpServerResponseImpl.end0(HttpServerResponseImpl.java:389)
    at io.vertx.core.http.impl.HttpServerResponseImpl.end(HttpServerResponseImpl.java:307)
    at io.vertx.core.http.impl.HttpServerResponseImpl.end(HttpServerResponseImpl.java:292)
    at com.nokia.doas.vertx.http.upload.SimpleFormUploadServer$1$1$2.handle(SimpleFormUploadServer.java:85)
    at com.nokia.doas.vertx.http.upload.SimpleFormUploadServer$1$1$2.handle(SimpleFormUploadServer.java:1)
    at io.vertx.core.http.impl.HttpServerFileUploadImpl.notifyEndHandler(HttpServerFileUploadImpl.java:213)
    at io.vertx.core.http.impl.HttpServerFileUploadImpl.lambda$handleComplete$165(HttpServerFileUploadImpl.java:206)
    at io.vertx.core.file.impl.AsyncFileImpl.lambda$doClose$226(AsyncFileImpl.java:470)
    at io.vertx.core.impl.ContextImpl.lambda$wrapTask$16(ContextImpl.java:335)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:358)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
    at java.lang.Thread.run(Unknown Source)


index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title></title>
</head>
<body>

<form action="/form" ENCTYPE="multipart/form-data" method="POST" name="wibble">
    choose a file to upload:<input type="file"  name="files" multiple="multiple"/><br>
    <input type="submit"/>
</form>

</body>
</html>
可以使用vert-web的来处理文件上传,但貌似fileUploads只能获得长度,文件名,并不能获得文件内容流,这个我并没有研究透,也许是可以的,有知道怎么用的同学可以留言互相学习探讨一下。router.route().handler(BodyHandler.create());

router.post("/some/path/uploads").handler(routingContext -> {

    Set<FileUpload> uploads = routingContext.fileUploads();
    // Do something with uploads....
});

多个文件上传是可以实现的vert.x在HTML中使用多个上传按钮,并使用uploadHandlerHttpRequestUploadHandler将被多次调用任何多个文件上传。


  HttpServerRequest request = routingContext.request();
    request.setExpectMultipart(true);
    request.endHandler(new Handler<Void>() {
        @Override
        public void handle(Void aVoid) {
            MultiMap entries = request.formAttributes();
            Set<String> names = entries.names();
            logger.info("UPLOAD_CONTENT: fileName = "+entries.get("fileName"));
            logger.info("UPLOAD_CONTENT: type = "+entries.get("type"));
            logger.info("UPLOAD_CONTENT: names = "+names);
            request.response().setChunked(true).end(createResponse("SUCCESS"));
        }
    });
    // This would be called multiple times
    request.uploadHandler(upload -> {

        upload.exceptionHandler(new Handler<Throwable>() {
            @Override
            public void handle(Throwable error) {
                logger.error("UPLOAD_CONTENT: Error while uploading content "+upload.filename());
                logger.error("UPLOAD_CONTENT: error = "+error.toString());
                error.printStackTrace();
                request.response().setChunked(true).end(createResponse("FAILURE"));
            }
        });
        upload.endHandler(new Handler<Void>() {
            @Override
            public void handle(Void aVoid) {
                logger.info("UPLOAD_CONTENT: fileName = "+upload.filename());
                logger.info("UPLOAD_CONTENT: name = "+upload.name());
                logger.info("UPLOAD_CONTENT: contentType = "+upload.contentType());
                logger.info("UPLOAD_CONTENT: size = "+upload.size());
                UtilityFunctions.uploadToS3(upload.filename(), "testfolder");

            }
        });
        upload.streamToFileSystem(upload.filename());
    });


您可以使用vertx-web轻松处理文件上传:

多个文件上传是可以实现的vert.x在HTML中使用多个上传按钮,并使用uploadHandlerHttpRequestUploadHandler将被多次调用任何多个文件上传。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页