download file using angular2 and spring - java

I am trying to download file using spring code and my code are running but there is no file downloaded in download folder. here my code are:-
#RequestMapping(value="/downloadRecordFile/{id}",
method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public void downloadRecordFile(#PathVariable("id") Long id,HttpServletRequest request,HttpServletResponse response) throws IOException {
File fileName = new File("C:\workarea\UplodedRecords\test_annotation.pdf");
if (fileName != null) {
if (!fileName.exists()) {
String errorMessage = "Sorry. The file you are looking for does not exist";
log.info(errorMessage);
OutputStream outputStream = response.getOutputStream();
outputStream.write(errorMessage.getBytes(Charset.forName("UTF-8")));
outputStream.close();
return;
}
String mimeType = URLConnection.guessContentTypeFromName(fileName.getName());
if (mimeType == null) {
mimeType = "application/octet-stream";
}
log.info("mimetype : " + mimeType);
response.setContentType(mimeType);
response.setHeader("Content-Disposition", String.format("inline; filename=\"" + fileName.getName() + "\""));
response.setContentLength((int) fileName.length());
InputStream inputStream = new BufferedInputStream(new FileInputStream(fileName));
//Copy bytes from source to destination(outputstream in this example), closes both streams.
FileCopyUtils.copy(inputStream, response.getOutputStream());
inputStream.close();
response.getOutputStream().flush();
}
}
}
My code is not givivng error or exception but it was not downloading file.
angular 2 code:-
function downloadRecord() {
alert("Downloading");
var record_id = 1234;
downloadRecordFile.query({id: record_id}, onSuccess);
}
here is my service js
(function() {
'use strict';
angular
.module('testApp')
.factory('downloadRecordFile', downloadRecordFile);
downloadRecordFile.$inject = ['$resource'];
function downloadRecordFile($resource) {
var resourceUrl = 'api/downloadRecordFile/:id';
return $resource(resourceUrl, {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
if (data) {
data = angular.fromJson(data);
}
return data;
}
}
});
}
})();
Is there any error in code please help me.

Related

Text file is not downloading in spring mvc 3

I am able to create the file but not able to download it. I am trying to download the file by an ajax call. I am able to receive the file name and file content and successfully able to write the content in a file in application directory but I'm not able to download that file. My code is given bellow :-
The Ajax Code -:
downloadButton.onclick = function() {
//alert(payLoadID);
$.ajax({
type: "POST",
url: "payloadAjax",
data: { payloadData: document.getElementById("modal_paragraph").innerHTML, id: payLoadID },
success : function(data) {
alert("SUCCESS: " +data);
// modal.style.display = "none";
// $("body").css("overflow","auto");
},
error : function(e) {
alert("ERROR: "+ e);
},
done : function(e) {
alert("DONE");
}
})
}
Here is the java code -:
#RequestMapping(value = "/payloadAjax", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)//, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public #ResponseBody
void download(#RequestParam("payloadData") String payloadData, #RequestParam("id") String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("id : " +fileName);
System.out.println("payloadData : " +payloadData);
/* File creation code is here. */
String FOLDER = "/downloadDir";
String FILE_NAME = fileName +".txt";
String appPath = request.getRealPath("");
System.out.println("appPath = " + appPath);
File downloadDirectory = new File(appPath + FOLDER);
if(!downloadDirectory.exists() || !downloadDirectory.isDirectory()) {
downloadDirectory.mkdir();
System.out.println("Directory Created");
} else {
System.out.println("Directory already exists.");
}
File uploadFile = new File(downloadDirectory, FILE_NAME);
if(uploadFile.exists()) {
uploadFile.delete();
System.out.println(uploadFile.getName() +" Has been deleted.");
}
try {
uploadFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("New File successfully created.");
try
{
PrintWriter writer = new PrintWriter(uploadFile, "UTF-8");
writer.println(payloadData);
writer.flush();
writer.close();
System.out.println("File successfully written.");
}
catch(Exception ex) {
ex.printStackTrace();
}
if (uploadFile.exists()) {
System.out.println("Upload file exists. Ready to download....");
} else {
System.out.println("Sorry File not found!!!!");
}
/*File creation code successfully completed.*/
/*File download code starts here */
/*HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_HTML);
headers.setContentLength(uploadFile.length());
headers.setContentDispositionFormData("attachment", "Soubhab_Pathak.txt");
InputStreamResource isr = new InputStreamResource(new FileInputStream(uploadFile));
return new ResponseEntity<InputStreamResource>(isr, headers, HttpStatus.OK);*/
if(response == null) {
System.out.println("Response is null.");
} else {
System.out.println("Response is not null.");
}
System.out.println("111");
OutputStream out = response.getOutputStream();
System.out.println("112");
FileInputStream in = new FileInputStream(uploadFile);
System.out.println("113");
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.setHeader("Content-Disposition", "attachment; filename=" + FILE_NAME);
response.setHeader("Content-Length", uploadFile.length() +"");
FileCopyUtils.copy(in, out);
System.out.println("114");
response.flushBuffer();
System.out.println("115");
/*File download code completes here.*/
}
The log is as follows
Any idea?
Finally I am able to solve the problem. This also an example of how to download a string as file in Spring MVC using ajax. Solution is as follows -:
1) one controller action to receive the string from ajax call and store that string in a file in the application server.
2) another controller action where you need to write file download code and this action will receive a GET request.
3) in the ajax call in the success part just call the second action method to download the file.
Now the code is working fine.

Download the byte array as a original file in AngularJS from server

I have the below requirement,
Java server will send the below details by reading the file from server (it can be pdf, doc or image)
Java code:
public static byte[] downloadFileAsStream(String fileName) throws IOException, MalformedURLException
File file = new File(fileName);
if (!file.exists()) {
// File not found
return null;
}
try {
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
return readFileAsByte(file.getAbsolutePath());
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
private static byte[] readFileAsByte(String filePath) {
try {
Path path = Paths.get(filePath);
return Files.readAllBytes(path);
} catch (IOException ex) {
ex.printStackTrace();
}
return new byte[0];
}
server will return the file as byte array, then this needs to be converted as the original file AngularJS and download
You need to add the response header in server side like below.
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=sample.pdf");
The following code may be used to create a file on client side based on the response from server:
$http.post("<SERVER_URL>", "<PARAMS_IF_ANY>", {
responseType:'arraybuffer'
}).success(function(data, status, headers) {
var contentType = headers["content-type"] || "application/octet-stream";
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (urlCreator) {
var blob = new Blob([data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = "download.pdf"; //you may assign this value from header as well
a.click();
window.URL.revokeObjectURL(url);
}
}

How to clean up temporary file after response in JAX-RS REST Service?

I am returning a temporary file from my JAX-RS REST Service like below:
#GET
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFile() {
File file = ... // create a temporary file
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"" ) //optional
.build();
}
What is the correct way of removing this temporary file after the response has been processed? Is the JAX-RS implementation (like Jersey) supposed to do this automatically?
You can pass an instance of StreamingOutput that copies the content of the source file to the client output and eventually deletes the file.
final Path path = getTheFile().toPath();
final StreamingOutput output = o -> {
final long copied = Files.copy(path, o);
final boolean deleted = Files.deleteIfExists(path);
};
return Response.ok(output).build();
final File file = getTheFile();
return Response.ok((StreamingOutput) output -> {
final long copied = Files.copy(file.toPath(), output);
final boolean deleted = file.delete();
}).build();
The example on https://dzone.com/articles/jax-rs-streaming-response looks more helpful than the brief reply from Jin Kwon.
Here is an example:
public Response getDocumentForMachine(#PathParam("custno") String custno, #PathParam("machineno") String machineno,
#PathParam("documentno") String documentno, #QueryParam("language") #DefaultValue("de") String language)
throws Exception {
log.info(String.format("Get document. mnr=%s, docno=%s, lang=%s", machineno, documentno, language));
File file = new DocFileHelper(request).getDocumentForMachine(machineno, documentno, language);
if (file == null) {
log.error("File not found");
return Response .status(404)
.build();
}
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream out) throws IOException, WebApplicationException {
log.info("Stream file: " + file);
try (FileInputStream inp = new FileInputStream(file)) {
byte[] buff = new byte[1024];
int len = 0;
while ((len = inp.read(buff)) >= 0) {
out.write(buff, 0, len);
}
out.flush();
} catch (Exception e) {
log.log(Level.ERROR, "Stream file failed", e);
throw new IOException("Stream error: " + e.getMessage());
} finally {
log.info("Remove stream file: " + file);
file.delete();
}
}
};
return Response .ok(stream)
.build();
}

How can i make this content be available for "save as"?

this is my code from the servlet:
private void createLog(HttpServletResponse response) throws IOException {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename=file.txt");
String s = "Hello world";
InputStream input = new ByteArrayInputStream(s.getBytes("UTF8"));
int read = 0;
byte[] bytes = new byte[1024];
OutputStream os = response.getOutputStream();
while ((read = input.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
}
and this is my ajax-call
$("#test").click(function(){
$.ajax({
type: 'POST',
url: 'myServlet',
data: { request : "createLog" }
})
.success(function(response) {
console.log("all good");
})
.error(function(response){
})
.done(function(){
});
});
so i get the content of the file, but only in the response in the browser. I want to be able to download this file, so i can save it on my computer.
what am i missing?
Thanks for any help!

How to download file in browser using spring mvc?

I have file on the server & that I want to download on my machine using browser. But I am not getting an option from browser to download the file.
My code is
JSP
<div id="jqgrid">
<table id="grid"></table>
<div id="pager"></div>
</div>
JS
jq("#grid").jqGrid({
....
onCellSelect: function(rowid, index, contents, event) {
...
var fileName = jQuery("#grid").jqGrid('getCell',rowid,'fileName');
$scope.downloadFile(fileName);
}
});
$scope.downloadFile = function(fileName) {
$http({
url: "logreport/downLoadFile",
method: "GET",
params: {"fileName": fileName}
});
};
Controller
#RequestMapping(value = "/downLoadFile", method = RequestMethod.GET)
public void downLoadFile(HttpServletRequest request, HttpServletResponse response) {
try {
String fileName = request.getParameter("fileName");
File file = new File(filePath +"//"+fileName);
InputStream in = new BufferedInputStream(new FileInputStream(file));
response.setContentType("application/xlsx");
response.setHeader("Content-Disposition", "attachment; filename="+fileName+".xlsx");
ServletOutputStream out = response.getOutputStream();
IOUtils.copy(in, out);
response.flushBuffer();
} catch (Exception e) {
e.printStackTrace();
}
}
I am not getting any exception but not sure why browser dialog is not opening to download the file. Also where is it exactly downloading the file?
#SotiriosDelimanolis was right. File download is not possible using ajax request.
Simply use 'window.location'.
$scope.downloadFile = function(fileName) {
window.location.href = 'logreport/downLoadFile?fileName=asdad1';
};
I didn't have enough credit to give a comment so wiritting here.. Thanks user1298426. I was strugling like anything for this. I was trying with AJAX. With window.location.href, I can download file in browser...
MY javascript code is as follows:
jQuery('#exportToZip').click(function() {
window.location.href = '*****';
});
*****: is the url mapping that I have in controller.
#RequestMapping(value = "/****")
#ResponseBody
public void downloadRequesthandler(HttpServletRequest request,HttpServletResponse response) {
String status;
try {
filedownloader.doGet(request, response);
} catch (ServletException e) {
status="servlet Exception occured";
e.printStackTrace();
} catch (IOException e) {
status="IO Exception occured";
e.printStackTrace();
}
//return status;
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
// construct the complete absolute path of the file
File downloadFile = new File(filePath);
System.out.println("downloadFile path: "+ filePath);
FileInputStream inputStream = new FileInputStream(downloadFile);
// get MIME type of the file
String mimeType = context.getMimeType(fullPath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}
System.out.println("MIME type: " + mimeType);
response.setContentLength((int) downloadFile.length());
// set headers for the response
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",downloadFile.getName());
response.setHeader(headerKey, headerValue);
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
System.out.println("buffer: "+ buffer.length);
int bytesRead = -1;
// write bytes read from the input stream into the output stream
//be carefull in this step. "writebeyondcontentlength" and "response already committed" error is very common here
while ((bytesRead = inputStream.read(buffer))!=-1 ) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
}
Trying to download file with ajax is a blunder....
cheers......
Instead of using IOUtils copy method
ServletOutputStream out = response.getOutputStream();
IOUtils.copy(in, out);
You can use following :
ServletOutputStream out = response.getOutputStream();
byte[] bytes = IOUtils.toByteArray(in);
out.write(bytes);
out.close();
out.flush();
Hope this will work.

Categories