How to ZIP the downloaded file using spring boot - java

I am beginner in java and would like some assistance with zipping a downloaded file using rest api call to MSSQL backend. Below is the code snippet which takes the ID as input parameter, fetches the record specific for that ID and downloads it locally.
I now need the code modified to Zip the file when it is downloading.
#GetMapping("/message/save")
#CrossOrigin(origins = "*")
public ResponseEntity<byte[]> download(#RequestParam("id") Long id) throws Exception {
Optional<MessageEntity> messageRecord = messageRepository.findById(id);
MessageEntity messageEntity = messageRecord.get();
ObjectMapper objectMapper = new ObjectMapper();
String xml = objectMapper.writeValueAsString(messageEntity);
byte[] isr = xml.getBytes();
String fileName = "message.zip";
HttpHeaders respHeaders = new HttpHeaders();
respHeaders.setContentLength(isr.length);
respHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
respHeaders.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
return new ResponseEntity<byte[]>(isr, respHeaders, HttpStatus.OK);
}
I expect the output to be a zipped file.

I'm not sure that I understood your problem clearly. But I assume that you need just make zip from string:
#GetMapping("/message/save")
#CrossOrigin(origins = "*")
public void download(#RequestParam("id") Long id, HttpServletRequest request,
HttpServletResponse response) throws Exception {
MessageEntity messageEntity = messageRepository.findById(id).orElseThrow(() -> new Exception("Not found!"));
String xml = new ObjectMapper().writeValueAsString(messageEntity);
String fileName = "message.zip";
String xml_name = "message.xml";
byte[] data = xml.getBytes();
byte[] bytes;
try (ByteOutputStream fout = new ByteOutputStream();
ZipOutputStream zout = new ZipOutputStream(fout)) {
zout.setLevel(1);
ZipEntry ze = new ZipEntry(xml_name);
ze.setSize(data.length);
zout.putNextEntry(ze);
zout.write(data);
zout.closeEntry();
bytes = fout.getBytes();
}
response.setContentType("application/zip");
response.setContentLength(bytes.length);
response.setHeader("Content-Disposition",
"attachment; "
+ String.format("filename*=" + StandardCharsets.UTF_8.name() + "''%s", fileName));
ServletOutputStream outputStream = response.getOutputStream();
FileCopyUtils.copy(bytes, outputStream);
outputStream.close();
}

Related

How to download csv file using spring boot controller with contents?

I am facing the issue while downloading the csv file. I have created get api in spring boot and wanted to download the file through that api. Here is my code.
#GetMapping(value = "/citydetails/download")
public ResponseEntity<Object> getCityDetails() throws IOException {
System.out.println("Starting the rest call.");
FileWriter filewriter = null;
service = new LocalityService();
try {
List<CityDetails> details = service.getCityDetailsList();
if (details.isEmpty()) {
System.out.println("List is empty.");
}
StringBuilder fileContent = new StringBuilder("STATE,DISTRICT,CITY,VILLAGE,PIN\n");
for (CityDetails data : details)
fileContent.append(data.getStatename()).append(data.getDistrict()).append(data.getCity())
.append(data.getVillage()).append(data.getPindode());
XSSFWorkbook workbook = service.saveFileContents(details);
String filename = "C:\\Users\\" + System.getProperty("user.name") + "\\Downloads\\cityDetails.csv";
FileOutputStream out = new FileOutputStream(filename);
File file = new File("cityDetails.csv");
workbook.write(out);
out = new FileOutputStream(file);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("text/csv"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + "cityDetails.csv" + "\"")
.body(file);
} catch (Exception ex) {
System.out.println("Failed to execute rest" + ex.getStackTrace() + "Locale: " + ex.getLocalizedMessage());
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), "false");
return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
} finally {
if (filewriter != null)
filewriter.close();
}
}
Exception:
Here i have used XSSFWorkbook to save my content to csv. Now i wanted to download the csv file through Rest api which will contain the data.I have tried multiple ways but i am getting empty file.With the above code it will save the csv file in download folder in windows machine, but i want this api to work on every system so I wanted to download the csv file with contents instead of saving it to specific location. I am facing the issue, how to resolve that?
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet=wkb.createSheet("sheet1");
HSSFRow row1=sheet.createRow(0);
HSSFCell cell=row1.createCell(0);
cell.setCellValue("table_demo");
sheet.addMergedRegion(new CellRangeAddress(0,0,0,3));
//input Excel date
HSSFRow row2=sheet.createRow(1);
row2.createCell(0).setCellValue("name");
row2.createCell(1).setCellValue("class");
row2.createCell(2).setCellValue("score_1");
row2.createCell(3).setCellValue("score_2");
HSSFRow row3=sheet.createRow(2);
row3.createCell(0).setCellValue("Jeams");
row3.createCell(1).setCellValue("High 3");
row3.createCell(2).setCellValue(87);
row3.createCell(3).setCellValue(78);
//output Excel file
OutputStream output=response.getOutputStream();
response.reset();
response.setHeader("Content-disposition", "attachment; filename=details.xls");
response.setContentType("application/msexcel");
wkb.write(output);
output.close();
This code can get a simple excel file
//image
#GetMapping(value = "/image")
public #ResponseBody byte[] getImage() throws IOException {
InputStream in = getClass()
.getResourceAsStream("/com/baeldung/produceimage/image.jpg");
return IOUtils.toByteArray(in);
}
//normal file
#GetMapping(
value = "/get-file",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE
)
public #ResponseBody byte[] getFile() throws IOException {
InputStream in = getClass()
.getResourceAsStream("/com/baeldung/produceimage/data.txt");
return IOUtils.toByteArray(in);
}

Spring MVC video type forward and send as bytes[]

I'm trying to create a video platform with Spring MVC and Angular2. But I can not get this video going backwards or forwards. I also have not got the rest controller to send the video to pieces of bytes, just send it whole.
#RequestMapping(value = "/method2/{name}", method = RequestMethod.GET)
public void getDownload(HttpServletResponse response, HttpServletRequest request,#PathVariable String name)
throws IOException, ServletException {
String filePath;
if (name.contains("webm")) {
filePath = webm;
System.out.println("WEBM");
} else if (name.contains("mp4")) {
filePath = mp4;
System.out.println("MP4");
} else {
filePath = mkv;
System.out.println("MKV");
}
// Get your file stream from wherever.
ServletContext context = request.getServletContext();
File downloadFile = new File(filePath);
FileInputStream inputStream = new FileInputStream(downloadFile);
// Set the content type and attachment header.
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
response.setHeader(headerKey, headerValue);
String mimeType = context.getMimeType(filePath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}
response.setContentType(mimeType);
// Copy the stream to the response's output stream.
IOUtils.copy(inputStream, response.getOutputStream());
response.flushBuffer();
}
ant my html
<video width='360' height='240' [vgMedia]="media" #media id="singleVideo" preload="auto" crossorigin>
<source src="********/movies/method2/mp4" type="video/mp4">
</video>
I've looked at many posts right here and none has worked for me to get this.
EDIT1. Method3
#RequestMapping(method = RequestMethod.GET, value = "/method3/{name}")
public StreamingResponseBody stream(#PathVariable String name) throws FileNotFoundException {
String filePath;
if (name.contains("webm")) {
filePath = webm;
System.out.println("WEBM");
} else if (name.contains("mp4")) {
filePath = mp4;
System.out.println("MP4");
} else {
filePath = mkv;
System.out.println("MKV");
}
File videoFile = new File(filePath);
final InputStream videoFileStream = new FileInputStream(videoFile);
return (os) -> {
readAndWrite(videoFileStream, os);
};
}
private void readAndWrite(final InputStream is, OutputStream os) throws IOException {
byte[] data = new byte[2048];
int read = 0;
while ((read = is.read(data)) > 0) {
os.write(data, 0, read);
}
os.flush();
}
Thanks.
Have a look this post which I wrote sometime back on how to play streaming video by using StreamingResponseBody available in Spring.

Spring OutputStream - download pptx with IE

I use this Java code to download files from a web application:
#RequestMapping(value = "/filedownloads/filedownload/{userid}/{projectid}/{documentfileid}/{version}/", method = RequestMethod.GET)
public void filesDownload(final #PathVariable("userid") String userId, final #PathVariable("projectid") String projectId,
final #PathVariable("documentfileid") String documentFileId, final #PathVariable("version") String version,
final HttpServletResponse response) throws IOException, BusinessException {
...
final String fileName = "filename=" + documentFile.getFileName();
final InputStream is = new FileInputStream(filePath);
response.setHeader("Content-Disposition", "inline; " + fileName);
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
}
if I will download a pptx- file I get the following IE- page:
What I want to do is to open the downloaded file in Powerpoint.
My question now would be if there is a header setting in order to open this file with the right application (in this case Powerpoint)
Simply try to set the Content Type header properly which is application/vnd.openxmlformats-officedocument.presentationml.presentation in case a pptx, as next:
response.setContentType(
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
);
response.setHeader(
"Content-Disposition",
String.format("inline; filename=\"%s\"", documentFile.getFileName())
);
response.setContentLength((int) new File(filePath).length());
Here is the list of mime types corresponding to Office 2007 documents.
Here is a little sample code from a Spring MVC Controller:
#RequestMapping("/ppt")
public void downloadPpt(HttpServletRequest request, HttpServletResponse response) throws IOException {
Resource resource = new ClassPathResource("Presentation1.pptx");
InputStream resourceInputStream = resource.getInputStream();
response.setHeader("Content-Disposition", "attachment; filename=\"Presentation1.pptx\"");
response.setContentLengthLong(resource.contentLength());
byte[] buffer = new byte[1024];
int len;
while ((len = resourceInputStream.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, len);
}
}
By setting the Content-Disposition to attachment, you're telling the browser to download this file as an attachment and by supplying the correct file name with extension, you're telling the Operating System to use whatever application the user normally uses to open a file of this type. In this case it will be MS Power Point.
This way you can get away with not knowing exactly what version of Power Point the file was created with.
I have tested code in IE-11 its work fine. See below code i.e
#RequestMapping(value = "/downloadfile", method = RequestMethod.GET)
#ResponseBody
public void downloadfile(HttpServletRequest request, HttpServletResponse response) throws Exception {
ServletOutputStream servletOutputStream = null;
try {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=downloadppt.pptx");
byte[] ppt = downloadFile();
servletOutputStream = response.getOutputStream();
servletOutputStream.write(ppt);
} catch (Exception e) {
throw e;
} finally {
servletOutputStream.flush();
servletOutputStream.close();
}
}
Generate bytes from saved pptx file.
public byte[] downloadFile() throws IOException {
InputStream inputStream = new FileInputStream(new File("e:/testppt.pptx"));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// Transfer bytes from source to destination
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
byteArrayOutputStream.write(buf, 0, len);
}
inputStream.close();
byteArrayOutputStream.close();
return byteArrayOutputStream.toByteArray();
}
That's it, you are able to download pptx file. Hope code help you, if you have any query or doubt then we can discuss or if any suggestions. Thank you

open the pdf in browser using spring and java

below i am reading the pdf from the data base... and i am trying to open the pdf file in browser... but instead of opening in browser it always downloaded...the code is given below please help me to open the pdf in browser instead of asking for download....
#RequestMapping(value = "account/documents/{id}", method = RequestMethod.GET)
public void downloadDocument(HttpServletRequest request,
HttpServletResponse response, #PathVariable("id") String docId)
throws Exception {
HttpSession session = request.getSession(true);
int accountId = (Integer) session.getAttribute("ownerAccountId");
Map<String, String> docMap = DbInteractor.getUploadedDocsByDocId(
Integer.valueOf(docId), accountId);
String docName = docMap.get("name");
String typeName = docMap.get("type");
String[] fileName = docName.split("\\.(?=[^\\.]+$)");
typeName = typeName.replace(" ", "");
if (typeName.equals("CCD/CCR")) {
typeName = "CCDorCCR";
}
String filename = typeName + docId + "." + fileName[1];
System.out.println(filename);
FileInputStream fileInputStream = new FileInputStream(
Constants.DOCUMENTS_PATH + filename);
response.setHeader("Expires", "0");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
response.setHeader("Content-disposition", "inline; filename="
+ docName);
OutputStream os = response.getOutputStream();
IOUtils.copy(fileInputStream, os);
os.flush();
os.close();
}
can you please help me.....
You need to change content type so that, your browser recognizes the data. Add this line in your code -
response.setContentType("application/pdf");
Also, you can try with response.setHeader("Content-Disposition", "inline"); with and without attachment property. (As I am not sure and haven't checked it yet. :-))
Hope this helps.
I removed:
response.setHeader("Content-disposition", "inline; filename="+ docName);
and added:
response.setContentType("application/pdf");
and it worked for me.
This is my solution using ResponseEntity<byte[]>
#RequestMapping(value = "/export", method = RequestMethod.GET, produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<byte[]> getExport() {
ITextRenderer renderer = new ITextRenderer();
ByteArrayOutputStream boas = null;
try {
String inputFile = "files/templates/autodebit.html";
String outputFile = "files/generated/autodebit_"+filenameDate.format(new Date())+".pdf";
String html = new String(Files.readAllBytes(Paths.get(inputFile)));
final Document document = Jsoup.parse(html);
document.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
document.body().select(".DOC_GENERATED_DATE").html(readableDate.format(new Date()));
renderer.setDocumentFromString(document.html());
renderer.layout();
try (OutputStream os = Files.newOutputStream(Paths.get(outputFile))) {
renderer.createPDF(os);
os.close();
PdfReader reader = new PdfReader(outputFile);
boas = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, boas);
stamper.setPageAction(PdfWriter.PAGE_OPEN, new PdfAction(PdfAction.PRINTDIALOG), 1);
stamper.close();
} catch (DocumentException ex) {
Logger.getLogger(ReportController.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
Logger.getLogger(ReportController.class.getName()).log(Level.SEVERE, null, ex);
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = new ResponseEntity<>(boas.toByteArray(), headers, HttpStatus.OK);
return response;
}
Hope it helps!

Spring: how to download file?

I want to save zip archive from server to user computer. I have web page that shows some information about this file and has a download button. In my controller action on button simply redirect on homepage but I want to get data from database and save it to user machine with path is defined by user
The issue is that I don't know how I can get this path. Could you give me an example how I can do that?
In your controller method you can add this code to get file download
File file = new File("fileName");
FileInputStream in = new FileInputStream(file);
byte[] content = new byte[(int) file.length()];
in.read(content);
ServletContext sc = request.getSession().getServletContext();
String mimetype = sc.getMimeType(file.getName());
response.reset();
response.setContentType(mimetype);
response.setContentLength(content.length);
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
org.springframework.util.FileCopyUtils.copy(content, response.getOutputStream());
You don't have to know how to get the path, because the path is defined by the user :) But if your looking for the download path, check the source code of the website and where the download button links to. Usually you can see it in the beginning of the <form>.
If you are just looking for download a file:
public void download(String filename, String url) {
URL u;
InputStream is = null;
DataInputStream dis;
String s;
try{
u = new URL(url);
// throws an IOException
is = u.openStream();
dis = new DataInputStream(new BufferedInputStream(is));
FileWriter fstream = new FileWriter(filename);
BufferedWriter out = new BufferedWriter(fstream);
while ((s = dis.readLine()) != null) {
// Create file
out.write(s);
//Close the output stream
out.close();
}
}catch (Exception e){ //Catch exception if any
System.err.println("Error: " + e.getMessage());
}
is.close();
}
Hope this helps...
If you want to download from some external URL or from S3:::
#RequestMapping(value = "asset/{assetId}", method = RequestMethod.GET)
public final ResponseEntity<Map<String, String>> fetch(#PathVariable("id") final String id)
throws IOException {
String url = "<AWS-S3-URL>";
HttpHeaders headers = new HttpHeaders();
headers.set("Location", url);
Map<String, String> map = null;
ResponseEntity<Map<String, String>> rs =
new ResponseEntity<Map<String, String>>(map, headers, HttpStatus.MOVED_PERMANENTLY);
return rs;
}

Categories