在Vertx中处理多部分表单

时间:2016-04-04 11:35:05

标签: java multipartform-data multipart vertx3 vert.x

我有一个包含一些文本字段和一些上传文件的多部分表单。我需要在vertx处理程序中处理这个多部分发布请求,以便所有上传的文件(变量号)应该以块的形式读取(出于内存效率的目的)。我读取块(在foreach循环中)的那一刻,我想直接将其流式传输到文件。对于带文本字段的multipart,我想简单地将值存储到我的模型对象中。

我对vertx很陌生,因此寻找一个代码片段来实现这一点,但无法在vertx文档中的任何地方找到它。

3 个答案:

答案 0 :(得分:3)

你应该看看vertx-web。它包含您需要的内容:

router.route().handler(BodyHandler.create());
router.post("/some/path/uploads").handler(routingContext -> {
    MultiMap attributes = routingContext.request().formAttributes();
    // do something with the form data
    Set<FileUpload> uploads = routingContext.fileUploads();
    // Do something with uploads....
});

希望这会有所帮助。

答案 1 :(得分:1)

您可以分别处理文本字段和文件。这样可以简化您的处理。

request.handler(buffer -> {
   // decode the text field here
   // ...
}).uploadHandler(upload -> {
   // read upload files in chunks here
   // ...
}).endHandler(v -> {
   // upload request end here
   // ...
});

答案 2 :(得分:0)

我找到了另一种实时解码多部分数据的方法。借助netty解码器。请参见下面的代码段:

// the netty decoder used to decode multipart data in real time
HttpPostMultipartRequestDecoder decoder = null;

// create the decoder with reflect method
private void createDecoder(HttpServerRequest wrapper) {
    try {
        Class<?> wrapperClass = Class.forName("io.vertx.ext.web.impl.HttpServerRequestWrapper");
        Field delegateField = wrapperClass.getDeclaredField("delegate");
        delegateField.setAccessible(true);
        HttpServerRequestImpl request = (HttpServerRequestImpl) delegateField.get(wrapper);
        Field requestField = request.getClass().getDeclaredField("request");
        requestField.setAccessible(true);
        HttpRequest httpRequest = (HttpRequest) requestField.get(request);
        decoder = new HttpPostMultipartRequestDecoder(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE),
            httpRequest);
    } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException
        | IllegalAccessException ex) {
        log.error("create decoder failed {}.", ex.getMessage());
    }
    log.info("create decoder finished. {}", decoder);
}

router.route().handler(BodyHandler.create());
router.post("/some/path/uploads").handler(routingContext -> {
    // NOTE: in vertx, request is a class of 'HttpServerRequestWrapper'
    HttpServerRequest requestWrapper = routingContext.request();
    createDecoder(requestWrapper);
    
    // decode the buffer in real time
    request.handler(buffer -> {
        decoder.offer(new DefaultHttpContent(buffer.getByteBuf()));
        if (decoder.hasNext()) {
            // get the attributes and other data 
            // ...
        }
    });
});