vertx上传 - 文件正确方法

时间:2017-12-11 18:29:50

标签: file-upload vert.x

我在这里创建了2台服务器

    Router router = Router.router(vertx);
    router.route().handler(BodyHandler.create());
    router.post("/api/upload").handler(routingContext -> {
        System.out.println(routingContext.fileUploads().size());
        routingContext.response().end();
    });
    vertx.createHttpServer().requestHandler(req -> {
        router.accept(req);
    }).listen(8080, listenResult -> {
        if (listenResult.failed()) {
            System.out.println("Could not start HTTP server");
            listenResult.cause().printStackTrace();
        } else {
            System.out.println("Server started");
        }
    });
    // ==========================================
    vertx.createHttpServer().requestHandler(req -> {
        req.bodyHandler(buff -> {
            System.out.println(buff.toString() + " from client");
            req.response().end();
        });
    }).listen(8081, listenResult -> {
        if (listenResult.failed()) {
            System.out.println("Could not start HTTP server");
            listenResult.cause().printStackTrace();
        } else {
            System.out.println("Server started");
        }
    });

第一个来自vertx documentation

第二个来自https://github.com/vert-x3/vertx-examples/blob/master/web-client-examples/src/main/java/io/vertx/example/webclient/send/stream/Server.java

使用Postman进行测试时,两者都有效。

使用其他前端代码(例如:https://github.com/BBB/dropzone-redux-form-example)进行测试时,只有第二台服务器正常工作。

这是我在上面的github示例中更新的内容。

fetch(`http://localhost:8081/api/upload`, {
  method: 'POST',
  headers: {

  },
  body: body,
})
.then(res => {
  console.log('response status: ', res.statusText);
  return res.json();
})
.then(res => console.log(res))
.catch(err => {
  console.log("An error occurred");
  console.error(err);
});

在实践中,我更喜欢使用第一台服务器的方法。

由于两者都经过Postman测试,我认为服务器不是问题,需要在客户端进行调整。

有谁可以指出我应该添加到客户端的内容?

感谢。

修改

axios.post('http://localhost:50123/api/upload', fileData)
        .then(response => {
            console.log('got response');
            console.dir(response);
        })
        .catch(err => {
            console.log("Error occurred");
            console.dir(err);
        });
从前端传递文件时,

axios有效。

现在问题是使用Vertx Web Client进行单元测试。

fs.open("content.txt", new OpenOptions(), fileRes -> {
  if (fileRes.succeeded()) {
    ReadStream<Buffer> fileStream = fileRes.result();

    String fileLen = "1024";

    // Send the file to the server using POST
    client
      .post(8080, "myserver.mycompany.com", "/some-uri")
      .putHeader("content-length", fileLen)
      .sendStream(fileStream, ar -> {
        if (ar.succeeded()) {
          // Ok
        }
      });
  }
});

http://vertx.io/docs/vertx-web-client/java/#_writing_request_bodies的上述代码不适用于第一台服务器。 FileUploads是空的。

适用于第二名。

EDIT2

我决定使用一个简单的HttpClient代码,它也可以运行。 How can I make a multipart/form-data POST request using Java?

    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost uploadFile = new HttpPost("http://localhost:8080/upload");
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("field1", "yes", ContentType.TEXT_PLAIN);

// This attaches the file to the POST:
        File f = new File("./test.txt");
    builder.addBinaryBody(
            "file",
            new FileInputStream(f),
            ContentType.APPLICATION_OCTET_STREAM,
            f.getName()
    );

    HttpEntity multipart = builder.build();
    uploadFile.setEntity(multipart);
    CloseableHttpResponse response = httpClient.execute(uploadFile);
    HttpEntity responseEntity = response.getEntity();
    System.out.println(responseEntity.toString());

1 个答案:

答案 0 :(得分:0)

我不知道你的最后一个例子是如何运作的。您发布到http://localhost:8080/upload,但您的路线为/api/upload。在第二个示例中,使用端口8081,您只需忽略该路由,并假设您收到的任何内容都是文件上载。这是第二个例子“有效”的唯一原因。