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