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!
Related
I am trying to create a endpoint to render/serve PDF file.
I have gone through the following links to build the API, but still facing some issues.
link 1
link 2
Following is my code :
byte[] targetArray = null;
InputStream is = null;
InputStream objectData = object.getObjectContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(objectData));
char[] charArray = new char[8 * 1024];
StringBuilder builder = new StringBuilder();
int numCharsRead;
while ((numCharsRead = reader.read(charArray, 0, charArray.length)) != -1) {
builder.append(charArray, 0, numCharsRead);
}
reader.close();
objectData.close();
object.close();
targetArray = builder.toString().getBytes();
is = new ByteArrayInputStream(targetArray);
return ResponseEntity.ok().contentLength(targetArray.length).contentType(MediaType.APPLICATION_PDF)
.cacheControl(CacheControl.noCache()).header("Content-Disposition", "attachment; filename=" + "testing.pdf")
.body(new InputStreamResource(is));
When I hit my API using postman, I am able to download PDF file but the problem is it is totally blank. What might be the issue ?
There are multiple ways to download files from server, you can use ResponseEntity<InputStreamResource>, HttpServletResponse.Below are the two methods to download.
#GetMapping("/download1")
public ResponseEntity<InputStreamResource> downloadFile1() throws IOException {
File file = new File(FILE_PATH);
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment;filename=" + file.getName())
.contentType(MediaType.APPLICATION_PDF).contentLength(file.length())
.body(resource);
}
OR
You can use StreamingResponseBody to download large files. In this case server writes data to OutputStream at same time Browser read data which means its parallel.
#RequestMapping(value = "downloadFile", method = RequestMethod.GET)
public StreamingResponseBody getSteamingFile(HttpServletResponse response) throws IOException {
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=\"demo.pdf\"");
InputStream inputStream = new FileInputStream(new File("C:\\demo-file.pdf"));
return outputStream -> {
int nRead;
byte[] data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
System.out.println("Writing some bytes..");
outputStream.write(data, 0, nRead);
}
};
}
You can try to use apache commons IOUtils. Why reinvent wheel :)
1. Open a connection to remote server
2. Copy the inputStream to the destination file outputStream.
public void downloadFileFromRemoteLocation(String serverlocation, File destinationFile) throws IOException
{
try (FileOutputStream fos = new FileOutputStream( destinationFile )){
URL url = new URL(serverlocation);
URLConnection connection = url.openConnection();
IOUtils.copy( connection.getInputStream(), fos);
}
}
if you want to stick to just Java then look at snippet below
try {
// Get the directory and iterate them to get file by file...
File file = new File(fileName);
if (!file.exists()) {
context.addMessage(new ErrorMessage("msg.file.notdownloaded"));
context.setForwardName("failure");
} else {
response.setContentType("APPLICATION/DOWNLOAD");
response.setHeader("Content-Disposition", "attachment"+
"filename=" + file.getName());
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();
}
}
}
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.
i would like to open/show the file content in a browser but i dosen't work.
This is my code:
#WebServlet("/Download")
public class Download extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String name = request.getParameter("id");
String sep = File.separator;
File file = new File("C:" + sep + "FILE" + sep + name);
if(!file.exists())
{
response.getWriter().print("File not found");
return;
}
InputStream in = new FileInputStream(file);
byte[] buffer = new byte[4096];
int i = 0;
while((i = in.read(buffer)) != -1)
{
baos.write(buffer, 0, i);
}
response.setContentType("application/pdf");
response.setContentLength(baos.size());
response.setHeader("Content-Disposition", "inline; filename=help.pdf");
response.setHeader("Cache-Control", "cache, must-revalidate");
response.setHeader("Pragma", "public");
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
in.close();
baos.writeTo(bos);
baos.flush();
bos.flush();
bos.close();
}
}
I try to open that file with a servlet class.
I browser debugger i can see that response is coming in, usually in this format(JVBERi0xLjMNMSAwIG9iag08PC9UeXBl...).
Thanks for helping me
EDIT
on the jsp site i call the servlet with an AJAX call, looks like this where 'id' is the fileName which the user want to open.
function downloadFile(id) {
$.ajax({
url:"Download",
type:"POST",
data:"id="+id
});
}
i think you should add this code inside your ajax call in downloadFile(id) function.
success:function(response){
$("#<Some_SPAN_OR_TextAreaID>").show();
$("#<Some_SPAN_OR_TextAreaID").html(response.responseText);
}
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.
i have a result set which has got some values, i want to export the data which is there in result set as a text file with the save dialog.
how to do this in java?.
I have done the above requirement for excel and java like the following.
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment; filename=\"" + reportName + ".xls\"");
and
response.setHeader("Content-disposition", "attachment; filename=\"" + reportName + ".pdf\"");
response.setContentType("application/pdf");
UPDATE :
if(exportTo.equals("text")){
response.setContentType("text/plain");
response.setHeader("Content-disposition", "attachment; filename=\"" + reportName + ".txt\"");
try {
} catch (Exception e) {
// TODO: handle exception
}
}
in this
in try block how to set the contents which are avilable from resultset to a output stream and make it available.
the only difference is this :
response.setContentType("text/plain");
You can see a full example here ( http://www.mkyong.com/servlet/servlet-code-to-download-text-file-from-website-java/ )
UPDATE
This is a demo that I have developed and tested and works perfectly fine:
public class ServletDownloadDemo extends HttpServlet {
private static final int BYTES_DOWNLOAD = 1024;
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename=downloadname.txt");
String s = "Test\n\nText file contects!!";
InputStream input = new ByteArrayInputStream(s.getBytes("UTF8"));
int read = 0;
byte[] bytes = new byte[BYTES_DOWNLOAD];
OutputStream os = response.getOutputStream();
while ((read = input.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
}
}
It downloads a text file named downloadname.txt with the contents of String s.
UPDATE 2
String s = "";
while (rs.next()) {
s += rs.getString("column_name");
}
if (exportTo.equals("text")) {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename=downloadname.txt");
try {
InputStream input = new ByteArrayInputStream(s.getBytes("UTF8"));
int read = 0;
byte[] bytes = new byte[BYTES_DOWNLOAD];
OutputStream os = response.getOutputStream();
//data form resultset
while ((read = input.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
} catch (Exception e) {
// TODO: handle exception
}
}
You have to populate your ResultSet and place what you need in String s. That's all.