My Controller to which the request is mapped-
I return the value from AJAX, to the controller-
$.ajax({
type: 'GET',
dataType: 'json',
contentType:"application/json",
url:"/Putty/downloadProcess/?param="+param
});
#RequestMapping(value = "/downloadProcess", method = RequestMethod.GET)
protected void download(#RequestParam("param") String value, HttpServletResponse response)
throws ServletException, IOException {
Properties prop = new Properties();
InputStream input = new FileInputStream("config.properties");;
prop.load(input);
System.out.println(value);
String path = prop.getProperty("path.MS1");
String filepath= path.concat(value);
System.out.println(filepath);
File downloadFile = new File(filepath);
FileInputStream inStream = new FileInputStream(downloadFile);
String mimeType = "application/octet-stream";
System.out.println("MIME type: " + mimeType);
// modifies response
response.setContentType(mimeType);
response.setContentLength((int) downloadFile.length());
// forces download
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile);
response.setHeader(headerKey, headerValue);
System.out.println(response);
// obtains response's output stream
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inStream.close();
outStream.close();
This displays the filenames on my JSP
<c:forEach var="listValue" items="${files}">
<label onClick="download('${listValue}')">${listValue}</label>
<br>
</c:forEach>
The problem is that, I can see the MIME type on my console, along with the value returned by AJAX- The filename. But I do not get the Download dialog box, when I click on the file names, displayed on my JSP. Am I not handling the requests properly or I am missing something else.
Thanks!
Try it
ServletOutputStream out = response.getOutputStream();
response.setContentType("application/octet-stream");
if (file.isFile())
{
response.setHeader("Content-Disposition", "attachment;filename=\"" + downloadFile.getName() + "\"");
try (FileInputStream inputStream = new FileInputStream(downloadFile ))
{
IOUtils.copy(inputStream, out);
}
}
The Open/Save dialogue appears by default so we can not force anything. It is a browser specific settings that you cant change on the client side.
For Mozilla Firefox example :
Related
There is a page where i have files list. On cliking on any of the .txt it must get downloaded and a notification should be displayed as the notification we get in download anything on GoogleChrome.
This is my Js which is called after cliking on .txt files
Here i am doing is, i am getting the filename and the filepath of the selected file. And then using ajax sending those filename and filepath to the spring servlet.
if (options.downloadable) {
$(easyTree).find('.easy-tree-toolbar').append('<div class="fileDownload"><button class="btn btn-default btn-sm btn-primary"><span class="glyphicon glyphicon-circle-arrow-down"></span></button></div>');
$(easyTree).find('.easy-tree-toolbar .fileDownload > button').attr('title', options.i18n.downloadTip).click(function() {
var selected = getSelectedItems();
var fileName = $(selected).find(' > span > a').text();
alert("fileName**" + fileName);
var hrefValue = $(selected).find(' > span > a').attr('href');
alert("hrefValue**" + hrefValue);
if (selected.length <= 0) {
$(easyTree).prepend(warningAlert);
$(easyTree).find('.alert .alert-content').html(options.i18n.downloadNull);
} else {
$.ajax({
url: "/ComplianceApplication/downloadFileFromDirectory",
type: "GET",
data: {
hrefValue: hrefValue,
fileName: fileName
},
success: function(data) {
//$(selected).remove();
//window.location.reload();
},
error: function(e) {
}
});
}
});
}
This is my springController. Here I am getting all the data properly but the problem is file is not getting downloaded and am not even getting any error so that I can come to know what mistake I am doing.
#RequestMapping(value="/downloadFileFromDirectory",method = RequestMethod.GET)
public #ResponseBody void downloadFileFromDirectory(#PathVariable("fileName") String fileName,#RequestParam(value = "hrefValue") String hrefValue,HttpServletRequest request, HttpServletResponse response,Model model){
System.out.println("hrefValue***"+hrefValue);
String filePath = hrefValue;
ServletContext context = request.getSession().getServletContext();
File downloadFile = new File(filePath);
FileInputStream inputStream = null;
OutputStream outStream = null;
try {
inputStream = new FileInputStream(downloadFile);
response.setContentLength((int) downloadFile.length());
response.setContentType(context.getMimeType(downloadFile.getName()));
// response header
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
//String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
response.setHeader(headerKey, headerValue);
// Write response
outStream = response.getOutputStream();
IOUtils.copy(inputStream, outStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != inputStream)
inputStream.close();
if (null != outStream)
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Any suggestions ???
I usually use this kind of code with no problem:
public ResponseEntity<InputStreamResource> downloadFile(#PathVariable("idForm") String idForm)
{
try
{
File parent = new File(csvFilesPath);
File file = new File(parent, idForm+".csv");
HttpHeaders respHeaders = new HttpHeaders();
MediaType mediaType = new MediaType("text","csv");
respHeaders.setContentType(mediaType);
respHeaders.setContentLength(file.length());
respHeaders.setContentDispositionFormData("attachment", "file.csv");
InputStreamResource isr = new InputStreamResource(new FileInputStream(file));
return new ResponseEntity<InputStreamResource>(isr, respHeaders, HttpStatus.OK);
}
catch (Exception e)
{
String message = "Errore nel download del file "+idForm+".csv; "+e.getMessage();
logger.error(message, e);
return new ResponseEntity<InputStreamResource>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
The problem it's in you ajax code, so you can use JQuery File Download.
It's as simple as
$.fileDownload('/url/to/download.pdf');
Here you can see a tutorial
http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
I have a question that may been easy for some to answer...
I have this Java method:
#RequestMapping(value = "/exportEditableFields", method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
#ResponseBody
public void exportEditableFields(
#RequestParam(value = "conversationId") final String conversationId,#RequestParam(
value = "schoolId") final Long schoolId,
#RequestParam(value = "schoolAbbreviation") final String schoolAbbreviation,
final HttpServletResponse response) throws IOException {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy_hhmm");
School school = schoolService.getSchoolById(schoolId);
String fileName =
String.format("SDMS-%s-%s-Editable Fields-%s", school.getAbbreviation(), school.getName(),
dateFormat.format(new Date()));
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
fileName = fileName + ".xlsx";
response.setHeader("Content-Disposition", "attachment; filename=\""
+ fileName + "\"");
BufferedOutputStream bos =
new BufferedOutputStream(response.getOutputStream());
XSSFWorkbook workbook = new XSSFWorkbook();
exportManager.writeFieldRecords(bos, schoolId);
FileOutputStream fos = new FileOutputStream(fileName);
workbook.write(fos);
fos.close();
bos.flush();
response.flushBuffer();
}
I am invoking this method using EXTJS this way:
listeners: {
click: function(){
Ext.Ajax.request({
disableCaching: false,
method: 'GET',
params: {
conversationId : this.conversationId,
schoolId : Ext.getStore('DataStore').getProxy().extraParams.schoolId,
schoolAbbreviation: Ext.getStore('DataStore').getProxy().extraParams.schoolAbbreviation
},
url: 'export/exportEditableFields',
success: function(r, opts) {
var resp = Ext.decode(r.responseText);
var b =1;
Ext.DomHelper.append(Ext.getBody(), {
tag: 'iframe',
frameBorder: 0,
width: 0,
height: 0,
css: 'display:none;visibility:hidden;height:0px;',
src: resp.downloadUrl
}); },
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
}
});
}
the problem is from the browser I can't download the xlsx that the java method generates.
Any idea ?
how i should process the success response to download the file?
I am using EXTJS 4.2, Tomcat 7, Java 7
thanks a lot!
Thanks all! The problem was solved using window.open(url, '_self');
For downloading a file in ExtJs, you have to use form.submit() instead of Ajax.It's target should be iframe
I am done with writing the file content to pdf file on click of view, But it's not opening automatically.Can any one help. Thanks in advance.And please correct me if anything wrong here.
#RequestMapping(value = { "/view" }, method = RequestMethod.GET)
public static byte[] loadFile(#RequestParam("file_path") String file_path,#RequestParam("file_name") String fileName,HttpServletResponse response, HttpServletRequest request,HttpServletResponse resp) throws IOException, DocumentException {
FileInputStream inputStream = null;
try {
String filePath = file_path.replace("/", "\\");
File file = new File(filePath);
inputStream = new FileInputStream(file);
filePath.endsWith(".pdf");
return readFully(inputStream, filePath, fileName, resp, request,
resp);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
here i am calling the below method and written the code for opening a file automatically.
#ResponseBody
public static byte[] readFully(FileInputStream inputStream,
#RequestParam("file_path") String file_path,
#RequestParam("file_name") String fileName,
HttpServletResponse response, HttpServletRequest request,
HttpServletResponse resp) throws IOException, DocumentException {
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
Document doc = new Document();
PdfWriter.getInstance(doc, baos);
doc.open();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment; filename="
+ fileName + ".pdf");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
response.setHeader("Expires", "0");
response.setHeader("Pragma", "No-cache");
response.setContentLength(baos.size());
ServletOutputStream outn = response.getOutputStream();
outn.flush();
baos.writeTo(outn);
File f = new File("C:\\Users\\Downloads\\" + fileName + ".pdf");
if (f.exists()) {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().open(f);
} else {
System.out.println("Awt Desktop is not supported!");
}
} else {
System.out.println("File is not exists!");
}
System.out.println("Done");
return baos.toByteArray();
}
You can write your inputstream into spring fileInputStream.
You can do this just writing input stream in httpservletResponse.
Please change your all code with below method. You can achieve your goal.
#RequestMapping(value = { "/view" }, method = RequestMethod.GET)
#ResponseBody
public void loadFile(#RequestParam("file_path") String file_path,#RequestParam("file_name") String fileName,HttpServletResponse response, HttpServletRequest request,HttpServletResponse resp) throws IOException, DocumentException {
String filePath = file_path.replace("/", "\\");
File file = new File(filePath);
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Disposition","attachment;filename="+fileName);
response.setHeader("Content-Length", String.valueOf(file.length()));
try {
FileInputStream fileInputStream = new FileInputStream(file);
FileCopyUtils.copy(fileInputStream, httpServletResponse.getOutputStream());
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
UserEntityManager.java
#RequestMapping(value = "getImages.do", method = RequestMethod.GET)
public byte[] getImage(final String username) {
Blob img = null;
byte[] imgData = null;
sql = "SELECT UserPhoto FROM u_logininfo WHERE LoginName = ?";
try {
img = jdbcTemplate.queryForObject(sql, new Object[]{username}, new RowMapper<Blob>() {
#Override
public Blob mapRow(ResultSet rs, int arg1)
throws SQLException {
Blob blob = rs.getBlob("UserPhoto");
return blob;
}
});
imgData = img.getBytes(1, (int) img.length());
return imgData;
//File file = new File
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
And this is my controller
UserController.java
#RequestMapping(value = "getImages.do" , method = RequestMethod.GET)
private ModelAndView viewImages(Model model){
String userName = (String)SecurityContextHolder.getContext().getAuthentication().getName();
byte[] image = userEntityManager.getImage(userName);
model.addAttribute("images", image);
return new ModelAndView("Fun Zone/Photo");
}
and jsp
<div class="col-sm-2" style="margin-top: 288px; margin-left: 291px;">
<img src="getImages.do">
</div>
I want to display the image on the .jsp page using Spring MVC 3 But image not display in jsp.
I'd suggest you to rewrite the controller. There seems so many things that are not exactly the way it's supposed to be. Do something like this:
#RequestMapping(value = "getImages.do", method = RequestMethod.GET)
public void viewImages(HttpServletRequest request, HttpServletResponse response) throws IOException {
// get the image
String userName = (String)SecurityContextHolder.getContext().getAuthentication().getName();
byte[] image = userEntityManager.getImage(userName);
// get MIME type of the file
String mimeType = "application/octet-stream";
// set content attributes for the response
response.setContentType(mimeType);
response.setContentLength((int) image.length());
// set headers for the response
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=image.jpeg");
response.setHeader(headerKey, headerValue);
// get output stream of the response
OutputStream outStream = response.getOutputStream();
// get input stream and a fixed size buffer
InputStream is = new ByteArrayInputStream(image);
byte[] buffer = new byte[4096];
// write data into output stream
int read = -1;
while(read = in.read(buffer)) != -1) {
outStream.write(buffer, 0, read);
}
// close output stream
outStream.flush();
outStream.close();
}
And also get rid of that RequestMapping on UserEntityManager.
I´m trying to open a pdf that I have created using iText library in my browser, but it fails.
This is the code I´m using to send to browser
File file = new File(path);
try{
//InputStream stream=blob.getBinaryStream();
InputStream streamEntrada = new FileInputStream(file);
//ServletOutputStream fileOutputStream = response.getOutputStream();
PrintWriter print = response.getWriter();
int ibit = 256;
while ((ibit) >= 0)
{
ibit = streamEntrada.read();
print.write(ibit);
}
response.setContentType("application/text");
response.setHeader("Content-Disposition", "attachment;filename="+name);
response.setHeader("Pragma", "cache");
response.setHeader("Cache-control", "private, max-age=0");
streamEntrada.close();
print.close();
return null;
}
catch(Exception e){
return null;
}
}
I tried with FileOutputStream but isn´t works. I´m desperate.
Thank you.
Now, I´m trying this way, but it doesn´t work:
public class MovilInfoAction extends DownloadAction{
protected StreamInfo getStreamInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
//Here the creation of the PDF
//Storing data
PdfData dPdf = pdf.drawPDF(terminal);
String path = dPdf.getPath();//Path
String name = dPdf.getName()+".pdf";//Pdf´s name
String contentType = "application/pdf";//ContentType
response.setContentType(contentType);
response.setHeader("Content-Disposition","attachment; filename="+name);
response.setHeader("Cache-control", "private, max-age=0");
response.setHeader("Content-Disposition", "inline");
File file = new File(path);
byte[] pdfBytes = es.vodafone.framework.utils.Utils.getBytesFromFile(file);
return new ByteArrayStreamInfo(contentType, pdfBytes);
}
protected class ByteArrayStreamInfo implements StreamInfo {
protected String contentType;
protected byte[] bytes;
public ByteArrayStreamInfo(String contentType, byte[] bytes) {
this.contentType = contentType;
this.bytes = bytes;
}
public String getContentType() {
return contentType;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes);
}
}
}
You specify the mimetype as application/text, when it should be application/pdf.
You should set the Header and ContentType before you write the data.
And set the Content Type to application/pdf.
change
response.setContentType("application/text");
to
response.setContentType("application/pdf");
and if you want your pdf to open in browser then make following change
response.setHeader("Content-Disposition", "inline");
Put the filename in double quote "
response.setHeader("Content-Disposition","attachment; filename=\"" + attachmentName + "\"");
Android Default Browser requires GET Request. It does not understand POST Request and hence cannot download the attachment. You can send a GET request as by sending GET request, it resolved my problem. Android browser generates a GET request on its own and sends it back to server. The response received after second request will be considered final by the browser even if GET request is sent on first time by the servlet.