Below is the upload request saved in a file. In runtime I need read the file and replace the placeholder {{stream}} to inputstream data(stream data of a file which I need to upload)
--Content Boundary
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=US-ASCII
Content-Transfer-Encoding: 8bit
{"id":"docupload","body":{"file":[{}]}}
--Content Boundary
Content-Disposition: form-data; name="inputFile"; filename="file1.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Transfer-Encoding: binary
{{stream}}
--Content Boundary--
I used below method to convert upload file stream of data to string and then I will replace in placeholder,
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos); // workbook is instance of XSSFWorkbook which I used to create at runtime
return new String(bos.toByteArray(), StandardCharsets.UTF_8);
But when I try to download Im getting corrupted file. Help me with the process which Im doing wrongly. Thanks in advance
CodePudding user response:
I tried recreating the code, I had no problem getting it to work using toString() method:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
workbook.write(bos);
System.out.println(bos.toString(StandardCharsets.UTF_8););
} catch (IOException e) {
e.printStackTrace();
}
Have you tried using toStringMethod()? I hope this helps, if not please reply! I'll be happy to try and help if I can :)
CodePudding user response:
I have read your comment, and I think I understand better what is happening. Again, please correct me if I'm wrong. From what I gathered, you are trying to upload a file, process it using XSSFWorkbook on the server, save the output as an excel .xlsx spreadsheet, and return that back to the client.
The problem here is that if the input file is very big it might take a long time for XSSFWorkbook to process it. So I would go about the process a bit differently.
First, I'd upload the file I want processed with POST multipart, or however it may be convenient. (Btw, right now, {"id":"docupload","body":{"file":[{}]}} implies the file is empty, but I assume you missed out the data to keep the question short). The backend would then respond with 200 OK (or a useful response that lets the client know why the upload failed). The server can then start processing the file with XSSFWorkbook in a separate thread.
Second, the client can then occassionally poll the server whether the processing has completed. (Alternatively, WebSockets could be used here instead). Once the server completes the processing, it can return a response with 'Content-Disposition: attachment' header.
I think that the issue here is the fact that such 'heavy' tasks are asynchronous, because the caller doesn't know when it will finish (and we might get a request timeout).
In such situations, I think it may be best to split upload and processing task into separate HTTP operations, in order to keep the service RESTful.
I hope we cracked the case with this one! Please let me know how it goes. I'm more than happy to try and help if I can if I didn't quite get what you are asking for though :D