Download File in Java Spring rest api - java

I want to download a file and for that I have written this code:
public void downoadResume(#PathVariable("id") int id, HttpServletResponse response) {
try {
Applicant applicant = applicantService.getOne(id);
File file = new File(DocumentConstants.DOCUMENTS_PATH + "/" + applicant.getOriginalDocPath());
// get your file as InputStream
InputStreamReader is = new InputStreamReader(new FileInputStream(file.getAbsolutePath()));
// copy it to response's OutputStream
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
is.close();
response.flushBuffer();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ResourceNotFoundException e) {
e.printStackTrace();
}
}
But I am getting this kind of response instead of file, please check:
PK!�?�*��[Content_Types].xml �(���Oo�#��H|k���i�8=��X*���8Y���3i�o��I�RLHs���罟��3��g��G�hc��e5?
�Z|�ߕE?��Q.��P\�޿��7 ��ꀵX�OR�^?WX�?O���"��K����� �&�R�#��VC̦��QkG��3��%��P7�[�Z���Պ�T>�ʥ�9T\�݃+���1�thO�n�����dk�xP���g���&���g��pƦ���V-���3���O��a�?ġ�H���NZ�?c�˓qz�V2Y�3b��k����'��F/}(�i�ߞ`�{��wK�ۦ�]?����Z��w"���߿�r��p�<����g�x!>
��H!�9�}/=
���a�<��𬜫��#:����� ^ ���gQ'sȒGe7�x���x���h�K��G̻ޑ���9C���o٭��/��PK!���N_rels/.rels �(����JA���a�}7�
"���H�w"����w̤ھ�� �P�^����O֛���;�<�aYՠ؛`G�kxm��PY�[��g
Gΰino�/<���<�1��ⳆA$>"f3��\�ȾT�?I S?���������W����Y
ig�#��X6_�]7~
f��ˉ�ao�.b*lI�r?j)�,l0�%?�b�
6�i���D�_���, � ���|u�Z^t٢yǯ;!Y,}{�C��/h>��PK!����g�word/_rels/document.xml.rels �(����N�0��H�C�;�:`�n#�����N[��U�{{¦u۲K/��G����?���:��*4)K���H�+S��-{��c�#arQ�?�������b�� ��+��E>�q)+���?,AcƟ(�Z?m�!?E|8����`ӽ��<O�?��~�j|���Q�J�#ʥCGJp0�A�W�2a��m��s2~��OG����C��}�W������ a�z֯�n��H��?KG�?���e�cު�"�I�f�'�7,^?�����1r�'�;��*!���Fϔ�}�n,�?���?ܜ`Е��PQ,Q�?K���x߀��)�WT>)�:�88
5���;<oY
Can you please tell me what wrong I have done in this code?

You need to set the response headers and content-type which triggers the browser to treat the response content as a file and not as a web page:
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=download.xlsx");

It seems that you are downloading an xlsx file, Try the code below:
public void downoadResume(#PathVariable("id") int id, HttpServletResponse response) {
try {
Applicant applicant = applicantService.getOne(id);
File file = new File(DocumentConstants.DOCUMENTS_PATH + "/" + applicant.getOriginalDocPath());
response.reset();
response.resetBuffer();
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "attachment; filename=test.xlsx");
// get your file as InputStream
InputStreamReader is = new InputStreamReader(new FileInputStream(file.getAbsolutePath()));
// copy it to response's OutputStream
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
is.close();
response.flushBuffer();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ResourceNotFoundException e) {
e.printStackTrace();
}
}

Related

Download excel file with vue and spring

I'm trying to make an excel file with spring (Java) and then send it to Vue, so I can download the file with the web browser.
I made the excel file with a service in Java, but I don't know how and what I have to return to Vue.
#RequestMapping(value = "/getmathresume", method = RequestMethod.GET)
public FileOutputStream getMathResume()
{
//Long code with XSSFWorkbook();
//.
//.
//.
// Finally I Write the output to a file, but I don't want to save it locally, instead, the idea
// is send it to Front and download the file with the Browser.
try {
FileOutputStream fileOut = new FileOutputStream("poi-generated-file.xlsx");
workbook.write(fileOut);
fileOut.close();
workbook.close();
}catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
e.printStackTrace();
}
//Using the code from the accepted answer
try {
File file = new File("poi-generated-file.xlsx");
Files.copy(file.toPath(), response.getOutputStream());
String mimeType = URLConnection.guessContentTypeFromName(file.getName());
String contentDisposition = String.format("attachment; filename=%s", file.getName());
int fileSize = Long.valueOf(file.length()).intValue();
response.setContentType(mimeType);
response.setHeader("Content-Disposition", contentDisposition);
response.setContentLength(fileSize);
}catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
e.printStackTrace();
}
}
__________________________VUE CODE____________________________
getMathResume()
{
axios({
url: 'http://localhost:8081/user/getmathresume',
method: 'GET',
responseType: 'blob',
}).then((response) => {
var fileURL = window.URL.createObjectURL(new Blob([response.data]));
var fileLink = document.createElement('a');
fileLink.href = fileURL;
fileLink.setAttribute('download', 'matematica.xlsx');
document.body.appendChild(fileLink);
fileLink.click();
});
},
I don't think this is a hard thing to do, but I cannot find a tutorial to do something like this.
Hope someone can help me out.
EDIT: ADDED THE NEW CODE WORKING.
#RequestMapping(value = "/getmathresume", method = RequestMethod.GET)
public void getMathResume(HttpServletResponse response) {
try {
File file = new File("poi-generated-file.xlsx");
Files.copy(file.toPath(), response.getOutputStream());
String mimeType = URLConnection.guessContentTypeFromName(file.getName());
String contentDisposition = String.format("attachment; filename=%s", file.getName());
int fileSize = Long.valueOf(file.length()).intValue();
response.setContentType(mimeType);
response.setHeader("Content-Disposition", contentDisposition);
response.setContentLength(fileSize);
}catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
e.printStackTrace();
}
}

java download a file sourced from a database to PC

I am getting an image (jpeg or pdf) from a database and want to download it to the PC. However, the image is not recognised at !file.exists(). This points to File file = new File(resourceDetail.getResourseImage()); being incorrect. What is the correct way to code this please?
Note: resourceDetail.getResourseImage() is the actual image not a path.
My code is:
resourceDetail = MySQLConnection.resourceDownload(fileID);
FileInputStream stream = null;
try {
File file = new File(resourceDetail.getResourseImage());
System.out.println("resourceDetail.getResourseImage(): " + resourceDetail.getResourseImage());
if (!file.exists()) {
System.out.println("File does not exist: ");
// context.addMessage(new ErrorMessage("msg.file.notdownloaded"));
// context.setForwardName("failure");
} else {
System.out.println("File exist: ");
if (resourceDetail.getResourseImageType().equals("pdf")){
System.out.println("pdf: ");
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename='myfile.pdf'");
}else{
System.out.println("jpeg: ");
response.setContentType("image/jpeg");
response.setHeader("Content-Disposition", "attachment; filename='myfile.jpg'");
}
// response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
System.out.println("stream: ");
stream = new FileInputStream(file);
response.setContentLength(stream.available());
OutputStream os = response.getOutputStream();
os.close();
response.flushBuffer();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
resourceDetail.getResourseImage() got string data, you can directly write the data to response by using: OuputStream#write(bytes). In you case, just use ·os.write(resourceDetail.getResourseImage().getByets());` to do this.
The Sample code:
resourceDetail = MySQLConnection.resourceDownload(fileID);
try {
System.out.println(
"resourceDetail.getResourseImage(): " + resourceDetail.getResourseImage());
if (resourceDetail.getResourseImageType().equals("pdf")) {
System.out.println("pdf: ");
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename='myfile.pdf'");
} else {
System.out.println("jpeg: ");
response.setContentType("image/jpeg");
response.setHeader("Content-Disposition", "attachment; filename='myfile.jpg'");
}
response.setContentLength(resourceDetail.getResourseImage().length());
OutputStream os = response.getOutputStream();
os.write(resourceDetail.getResourseImage().getBytes());
os.close();
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
While this solution does not directly answer the issue with java it does give me a solution. I started with using jQuery which worked with Chrome and not IE. I was told it was not possible to active downloading images with jQuery and that I needed to do it via java. However, I have now found:
http://danml.com/download.html
Kind regards,
Glyn

Java.lang.IllegalStateException: Cannot call sendRedirect() after response has been committed

I'm trying to send an XLSX file to the client. Everything works, but I get the exception java.lang.IllegalStateException: Can not call sendRedirect() after the response has been committed. This is thrown when the file has already been sent to the client. Note that the file has already been created prior to this bit of code.
public String generateExcelCupon(HttpServletRequest request, HttpServletResponse response) {
try {
String nameFile = System.getProperty("user.home")+"/Desktop"+request.getParameter("nameFile")+".xlsx";
XSSFWorkbook workbook = new XSSFWorkbook();
response.setContentType("application/vnd.ms-excel");
PrintWriter outPut = response.getWriter();
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition", "attachment; filename=\""
+ request.getParameter("nameFile") + ".xlsx");
FileInputStream fileInputStream = new FileInputStream(nameFile);
int i;
while ((i = fileInputStream.read()) != -1) {
outPut.write(i);
}
fileInputStream.close();
outPut.close();
file.delete();
} catch (Exception ex) {
System.out.println(ex);
}
return "success";
}

How the response header is set

Why does the response header is set after a filenotfound exception.
Technically the headers are set only after getting the file.
try {
//codes
File file = new File(zipDestinationPath);
response.setContentType(new MimetypesFileTypeMap().getContentType(file));
response.setContentLength((int)file.length());
response.setHeader("content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
is = new FileInputStream(file);
FileCopyUtils.copy(is, response.getOutputStream());
} catch(FileNotFoundException e){
System.out.println("File Not Found.");
ServletOutputStream out = null;
try {
//i am not setting header here commentedit.
// response.setHeader("content-disposition", "attachment; filename=" + URLEncoder.encode("Error", "UTF-8"));
response.setContentType("text/plain;charset=ISO-8859-15");
out = response.getOutputStream();
System.out.println(("Invalid file path :" +zipDestinationPath).getBytes());
out.write(("Invalid file path :" +zipDestinationPath).getBytes());
out.flush();
out.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
Creating a File does not throw a FileNotFoundException. The FileNotFoundException is only thrown when you create the FileInputStream, at which point you've already set the headers. Try rearranging it like
File file = new File(zipDestinationPath);
is = new FileInputStream(file);
response.setContentType(new MimetypesFileTypeMap().getContentType(file));
response.setContentLength((int)file.length());
response.setHeader("content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));

Java HttpServlet how to download excel file

I am trying to add a function to my web app which lets the users download an excel file.
I'm trying to achieve this with the following code:
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
File file = new File("d:/test/test.xls");
response.setContentType("application/xls");
response.addHeader("Content-Disposition", "attachment; filename=test.xls");
response.setContentLength((int) file.length());
try {
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream responseOutputStream = response.getOutputStream();
int bytes;
while ((bytes = fileInputStream.read()) != -1) {
responseOutputStream.write(bytes);
}
fileInputStream.close();
responseOutputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I'm able to download the excel file with the above code, however the file is corrupted. If I open it with microsoft excel, I get a popup with the message:
"the file format and extension of don't match. the file could be corrupted or unsafe".
And the excel file is empty.
After running the code, the original file(d:/test/test.xls) gets also corrupted.
What am I doing wrong?
The official MIME type for Excel file .xls is application/vnd.ms-excel and for .xlsx is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.
Also, I would suggest doing response.reset() prior to writing to the output stream and responseOutputStream.flush() (important) prior to closing the response.
Try below code :
File file = null;
InputStream in = null;
OutputStream outstream = null;
try {
response.reset();
in = new FileInputStream(file);
response.setContentType("application/vnd.ms-excel");
response.addHeader("content-disposition", "attachment; filename=data.xls");
outstream = response.getOutputStream();
IOUtils.copyLarge(in, outstream);
}
catch (Exception e) {
out.write("Unable to download file");
}finally {
IOUtils.closeQuietly(outstream);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
if (file != null)
file.delete();
}
dont forgot to add apache commons-io-2.4 in your dependency

Categories

Resources