4

I created 2 servers here

    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");
        }
    });

The 1st one is from vertx documentation.

The 2nd one is from https://github.com/vert-x3/vertx-examples/blob/master/web-client-examples/src/main/java/io/vertx/example/webclient/send/stream/Server.java

When tested with Postman, both works.

When tested with other front-end codes, (example: https://github.com/BBB/dropzone-redux-form-example), only 2nd server works.

This is what I updated on the above github example.

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);
});

In practice, I prefer to use the approach to 1st server.

Since both are tested by Postman, I believe server is not an issue, and need to tweak on the client side.

Can anyone point out what I should be adding to the client?

Thanks.

Edit

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 works when passing a file from frontend.

Now the problem is unit-test using 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
        }
      });
  }
});

The above code from http://vertx.io/docs/vertx-web-client/java/#_writing_request_bodies doesn't work for 1st server. FileUploads is empty.

It works for 2nd.

Edit2

I decided to use a simple HttpClient code, and it works as well. 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());
william
  • 7,284
  • 19
  • 66
  • 106
  • I must say that using edits to change the matter of the question is very confusing. What is not working in the end? Client code? Your test code? – Alexey Soshin Dec 27 '17 at 16:32
  • Yes, I understand that. I tried to use comments, but my edits are too long for that. Currently, using `VertX` `WebClient.sendStream` is not working if the server is setup using `Routes`. It is used as a test. – william Dec 27 '17 at 17:29

1 Answers1

0

I don't see how your last example could work. You post to http://localhost:8080/upload, but your route is /api/upload. In your second example, with port 8081 you simply ignore the route, and assume that anything you receive is a file upload. That's the only reason second example "works".

Alexey Soshin
  • 16,718
  • 2
  • 31
  • 40
  • Thanks. I made a typo. It is /api/upload. The paths and the ports are getting messy since I created several examples, and copying it from there. But my question remains `WebClient.sendStream` is not receiving when usig `routes` – william Dec 27 '17 at 22:47