Reputation: 310
I am writing code which grab file store in database and send it as a response to client. But when i click on download button, it is sending empty text file as a response, but i need zip file. Where am i doing wrong? Could anyone help with this?
I have search on web and even on stackoverflow but didn't find any luck.
Method which grab all the uploaded files
public List<Filestore> documentCollectionBvg(Application app){
List<Filestore> candidateDocuments = new ArrayList<>();
Filestore profilePic = app.getCandidate().getProfilePic();
if(profilePic!=null){
candidateDocuments.add(profilePic);}
Filestore panDoc = app.getCandidate().getPanDocument();
if(panDoc!=null){
candidateDocuments.add(panDoc);}
Filestore aadharDoc = app.getCandidate().getAadhaarDocument();
if(aadharDoc!=null){
candidateDocuments.add(aadharDoc);
}
Filestore salarySlip = app.getCandidate().getSalarySlipDocument();
if(salarySlip!=null){
candidateDocuments.add(salarySlip);}
Filestore passportDoc = app.getCandidate().getPassportDocument();
if(passportDoc!=null){
candidateDocuments.add(passportDoc);}
return candidateDocuments;
}
controller
@GetMapping(value = "application/get-file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public @ResponseBody byte[] getFile(@RequestParam("appId")String appId) throws IOException {
NDataUtils nDataUtils=new NDataUtils();
Application app=applicationService.findByEncryptedId(appId);
BgvDocumentsDownload bgv=new BgvDocumentsDownload();
List<Filestore> srcFiles=bgv.documentCollectionBvg(app);
FileOutputStream fos = new FileOutputStream("multiCompressed.zip");
ZipOutputStream zipOut = new ZipOutputStream(fos);
FileInputStream fis=null;
for (Filestore srcFile : srcFiles) {
File fileToZip = new File(nDataUtils.getnDataPath()+srcFile.getFullFilePath());
fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
}
zipOut.close();
fos.close();
return IOUtils.toByteArray(fis);
}
Here NDataUtils is a class which return path for where. So don't get confuse with it.
After i click on download link, a file named "download" is download which is just a text file and complete empty.
If anyone can help, this will be kind of you.
Upvotes: 1
Views: 11893
Reputation: 160
Hope this helps, here fileLocation is my Absolute File path, you can customize your path in separate method.
public byte[] exportDocument(final String fileLocation, final String aEngineName, final String aJobId,
HttpServletResponse response)
throws IOException
{
String tempFileName = aEngineName + "_" + aJobId + ".zip";
response.addHeader("Content-Disposition", "attachment; filename=\"" + tempFileName + "\"");
LOG.info("Zipping of File Started");
//creating byteArray stream, make it bufferable and passing this buffer to ZipOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
ZipOutputStream zipOutputStream = new ZipOutputStream(bufferedOutputStream);
ArrayList<File> files = new ArrayList<>();
File folder = new File(fileLocation + "/out");
File[] listOfFiles = folder.listFiles();
if (listOfFiles != null)
{
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files.add(new File(listOfFiles[i].getAbsolutePath()));
}
}
}
//packing files
for (File file : files) {
//new zip entry and copying inputstream with file to zipOutputStream, then closing streams
zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
FileInputStream fileInputStream = new FileInputStream(file);
IOUtils.copy(fileInputStream, zipOutputStream);
fileInputStream.close();
zipOutputStream.closeEntry();
}
if (zipOutputStream != null)
{
zipOutputStream.finish();
zipOutputStream.flush();
IOUtils.closeSilently(zipOutputStream);
}
IOUtils.closeSilently(bufferedOutputStream);
IOUtils.closeSilently(byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
And RestController
@RequestMapping(value = "/export/{engineName}/{jobId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, method = RequestMethod.GET)
public byte[] exportDocument(@PathVariable("jobId") final @Nonnull String aJobId,
@PathVariable("engineName") final @Nonnull String aEngineName, HttpServletResponse aResponse)
throws Exception
{
....
byte[] output = mDataExportComponent.exportDocument(fileLocation, aEngineName, aJobId, aResponse);
return output;
.... }
Upvotes: 2
Reputation: 93
Maybe you can write it into the response directly. It can be something like this (not tested):
@GetMapping(value = "application/get-file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void getFile(@RequestParam("appId") String appId, final HttpServletResponse response) throws IOException
{
String fileName = "multiCompressed.zip";
NDataUtils nDataUtils = new NDataUtils();
Application app = applicationService.findByEncryptedId(appId);
BgvDocumentsDownload bgv = new BgvDocumentsDownload();
List<Filestore> srcFiles = bgv.documentCollectionBvg(app);
FileOutputStream fos = new FileOutputStream(fileName);
ZipOutputStream zipOut = new ZipOutputStream(fos);
FileInputStream fis = null;
for (Filestore srcFile : srcFiles)
{
File fileToZip = new File(nDataUtils.getnDataPath() + srcFile.getFullFilePath());
fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0)
{
zipOut.write(bytes, 0, length);
}
}
zipOut.close();
fos.close();
try{
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
byte[] content = IOUtils.toByteArray(fis);
out = response.getOutputStream();
out.write(content, 0, content.length);
out.flush();
}
catch (final Exception e)
{
if (!response.isCommitted())
{
response.setStatus(HttpURLConnection.HTTP_BAD_REQUEST);
}
}
finally
{
if (out != null)
{
out.close();
}
}
}
Upvotes: 0