I have the following JAVA controller:
@RequestMapping(value = "/data/upload", method = RequestMethod.POST)
public
@ResponseBody
void uploadData(@RequestParam("file") MultipartFile file) throws IOException {
logger.info("Received File for Ingestion");
dataUploadService.processData(file.getInputStream());
}
Node server side code:
serviceCall(serviceCallRequestData, request, finalResponse) {
logger.info('Making remote request: ' + JSON.stringify(serviceCallRequestData));
let file = request.files['file']; // file: Object {name: "sample_aspect_review_upload.csv", encoding: "7bit", mimetype: "text/csv", mv: }
let formData = new FormData();
formData.append('file', Buffer.from(file.data));
fetch(serviceCallRequestData.url, {
method: serviceCallRequestData.requestObject.method,
headers: serviceCallRequestData.requestObject.headers,
body: formData
}).then(response => {
if (response.status !== 200) {
logger.error(`Error while making http call requestData: ${JSON.stringify(serviceCallRequestData)}`);
finalResponse.status(500).send('Internal server error');
return;
}
return response.json();
}).then((json) => {
logger.info(`Returning response for aspect-review-file-upload: ${JSON.stringify(json)}`);
finalResponse.status(200).send(JSON.stringify(json));
}).catch((e) => {
logger.error(`Error while making http call requestData: ${JSON.stringify(serviceCallRequestData)} error: ${JSON.stringify(e)}`);
finalResponse.status(500).send('Internal server error');
});
}
Trying to upload a csv file like:
"product_id","review_id","aspect_id","rating","confidence_score","indices"
"pid","rid","aid",1,0.851955,"[{\"s\":0,\"e\":114,\"highlights\":[39,68]}]"
The upload happens easily from POSTMAN. See the below screenshot:
Getting an error in JAVA: Received Unknown exception org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present when I am not passing contentType header from React.
Getting an error in JAVA: org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found when I am passing contentType header from React as 'Content-Type': 'multipart/form-data'
The same Node server side code for a JAVA dropwizard controller as:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response uploadFile(
@FormDataParam("file") InputStream inputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail
) throws IOException {
logger.debug("Request to upload data file-name: {}", fileDetail.getName());
dataUploadService.processData(inputStream);
return Response.ok().build();
}
works correctly.
What am I doing wrong?
From curl of postman you can see the following command:
curl -i -X POST -H "Content-Type:multipart/form-data" -F "file=@\"/pathto/sample.csv\";type=text/csv;filename=\"sample.csv\"" 'http://localhost:8080/data/upload'
So i tried adding type=text/csv;filename=\"sample.csv\"
in the form-data
so this should work:
let file = request.files['file'];
let formData = new FormData();
formData.append("file", Buffer.from(file.data), {
filename: file.name,
contentType: file.mimetype,
});
fetch(serviceCallRequestData.url, {
method: serviceCallRequestData.requestObject.method,
headers: serviceCallRequestData.requestObject.headers,
body: formData
}).then(response => {
if (response.status !== 200) {}
});
Few speculations:
In your REST endpoint definition you specify file to be request parameter which is used to extract parameters from the URI itself, while multipart file upload sits within the body of the POST request.
Add consumes={}
and instead of @RequestParam
you can use @RequestBody
annotation:
@RequestMapping(value = "/data/upload", method = RequestMethod.POST,
consumes = {"multipart/mixed", "multipart/form-data"}
)
void uploadData(@RequestBody MultipartFile file) //body will be the whole JSON payload
OR even better use @RequestPart
where you can name the element:
@RequestMapping(value = "/data/upload", method = RequestMethod.POST,
consumes = {"multipart/mixed", "multipart/form-data"}
)
void uploadData(@RequestPart (value="file") MultipartFile file) //gets file from JSON
Provide options to FormData
:
form.append('file', Buffer.from(file.data), {
filename: 'image1.jpg', // ... OR:
filepath: 'photos/image1.jpg',
contentType: 'image/jpeg',
knownLength: 19803
});
form.submit('http://example.com/', function(err, res) {
if (err) throw err;
console.log('Done');
});
Can you confirm (using something like WireShark) what exactly gets sent from React?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With