I have a web site and I want to be able to download file in mobile devices.
I don´t have problem when I access to my web page and download an image from pc's browser but if I want to do from mobile device the image doesn't download, mobile's browser opens other page with image.
This is my code for this section:
#Override
public void download(String nameImage, HttpServletResponse response) {
ImageEntity image = imageRepository.findByName(nameImage);
response.setContentType("image/" + image.getExtension());
File localFile = new File(pathManager.getPathCompleteOfImageUpload()+nameImage);
try {
InputStream is = new FileInputStream(localFile);
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
and Header is
private void setHeader(HttpServletResponse response, String name) {
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", name);
response.setHeader(headerKey, headerValue);
}
Can you help me?
Thanks you so much!
Related
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();
}
}
I have a problem with uploading image from android application to spring server. First of all i have this method on my server:
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String fileUpload(#RequestBody MultipartFile file) {
System.out.println("post image");
try {
// Get the file and save it somewhere
byte[] bytes = file.getBytes();
System.out.println(bytes.length);
//save file in server - you may need an another scenario
Path path = Paths.get("file:///E:/together/images/" + file.getOriginalFilename());
Files.write(path, bytes);
} catch (IOException e) {
e.printStackTrace();
}
//redirect to an another url end point
return "redirect";
}
And in my android app i'am get uri of image from image gallery and try call post method
FileEntity fileEntity = new FileEntity(new File(getRealPathFromURI(uri)), "application/octet-stream");
new Requests.Async().execute(fileEntity);
ublic static class Async extends AsyncTask<FileEntity,Void,Void>{
#Override
protected void onPreExecute() {
restTemplate = RestTemplateSingleton.newInstance().getRestTemplate();
}
#Override
protected Void doInBackground(FileEntity... uris) {
try{
restTemplate.postForObject(Requests.insertImage(),uris[0],FileEntity.class);
}catch (HttpClientErrorException | HttpServerErrorException httpClientOrServerExc) {
return null;
}
return null;
}
}
but i get 500 http status when call this method. what's my mistake?
I save user uploaded images in FTP.
FTP service is running on server Server-A. The actual problem is when I want to see the uploaded image from the web application running in my local host everything works, but when I deploy the local application to Tomcat running on the same server Server-A, images are not displayed correctly.
The picture when I run the web application in local Tomcat:
The same picture when I run the web application in the remote Tomcat:
You can see that the second image is not displayed correctly. Also want to mention that the FTP is the same one.
I am using Spring with Apache FtpClient library for image upload/download functionality.
Controller source code:
#RequestMapping(value = "/{id:\\d+}/image", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
protected byte[] getUserImage(BaseForm form,
#PathVariable("id") int userId) {
try {
User user = checkToken(form.getToken());
log.info("/users/{id}/image [GET]. User: " + user + ", form: " + form + ", User id: " + userId);
FileWrapper image = service.getUserImage(userId);
if(image != null) {
return ftpService.downloadFtpFile(image.getName());
}
}
catch(Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
FtpService source code:
public byte[] downloadFtpFile(String filePath) throws IOException {
FTPClient client = new FTPClient();
try {
client.connect(host, port);
if(!client.login(username, password)) {
throw new AdminException("Invalid ftp username/password");
}
client.enterLocalPassiveMode();
try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
client.retrieveFile(filePath, outputStream);
return outputStream.toByteArray();
}
}
catch(Exception e) {
log.error(e.getMessage(), e);
}
finally {
if(client.isConnected()) {
client.logout();
client.disconnect();
}
}
return null;
}
Thanks in advance!
If you've not set the FTP transfer to be binary (as opposed to ASCII) it will "convert the line endings" (or what it thinks are line endings) which will corrupt the picture.
I have .apk file in my resources dir and I want to download it directly from Mobile devices.
All is fine when using Chrome, or when I try it in my PC, but when using default Android Browser I get a .htm file and a:
ClientAbortException: java.io.IOException: Write failure
I dont understand what is happens or if it´s a browser´s bug.
Exception thrown after some loops in:
out.write(outputByte, 0, 4096);
Any suggestions? Thanks!
This is my code:
#RequestMapping(method = RequestMethod.POST)
public String download(#ModelAttribute("apkDownload") #Valid ApkDownloadDTO apkDownload, ModelMap model, HttpServletRequest request,
HttpServletResponse response, BindingResult result) {
InputStream is = ApkDownloadController.class.getResourceAsStream("/apk/mine.apk");
try {
response.addHeader("Content-Description", "File Transfer");
response.addHeader("Content-Type", " application/vnd.android.package-archive");
response.addHeader("Content-Disposition", "attachment; filename=mine.apk");
response.addHeader("Content-Transfer-Encoding", "binary");
ServletOutputStream out = response.getOutputStream();
byte[] outputByte = new byte[4096];
while (is.read(outputByte, 0, 4096) != -1) {
out.write(outputByte, 0, 4096);
}
is.close();
out.flush();
out.close();
} catch (IOException e) {
log.error(e);
} finally {
try {
is.close();
} catch (IOException e) {
log.error(e);
}
}
return null;
}
Try Using some other browser other then default browser,
e.g UC Browser, Chrome, etc
You'll get to known then if its default browser problem or not
I am using Jasper Reports in my project for producing the reports in multiple formats. Although all the code examples run fine, I have ran into a conceptual issue.
I wrote this trivial code which produces a PDF at the browser as a download option:
#GET
#Path("/basicdbreport")
#Produces("application/pdf")
public Response basicDbReport(#Context ServletContext context,
#Context HttpServletResponse response) throws JRException,
IOException {
Connection connection = null;
byte[] reportBytes = null;
String reportName = "firstsqlexample";
File file = new File(path + reportName + JASPER_EXTENSION);
// check if compiled report exists
if (!file.exists()) {
compileReport(context.getRealPath(path + reportName + JRXML_EXTENSTION));
}
// input stream for filling the compiled report
InputStream compiledReportStream = context.getResourceAsStream(path
+ reportName + JASPER_EXTENSION);
try {
connection = dataSource.getConnection();
reportBytes = JasperRunManager.runReportToPdf(compiledReportStream,
new HashMap<String, Object>(), connection);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (reportBytes != null) {
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(reportBytes);
}
ResponseBuilder restResponse = Response.ok();
restResponse.header("Content-Disposition",
"attachment; filename=firstSQLReport.pdf");
return restResponse.build();
}
The code runs fine and I get a download prompt at the browser. However, when I dug deeper into the Jasper API I found a method runReportToPdfStream() method which would handle the output stream for me.
The new code looks something like this:
#GET
#Path("/basicdbreport")
#Produces("application/pdf")
public Response basicDbReport(#Context ServletContext context,
#Context HttpServletResponse response) throws JRException,
IOException {
ServletOutputStream outputStream = response.getOutputStream();
Connection connection = null;
String reportName = "firstsqlexample";
File file = new File(path + reportName + JASPER_EXTENSION);
// check if compiled report exists
if (!file.exists()) {
compileReport(context.getRealPath(path + reportName + JRXML_EXTENSTION));
}
// input steam to fill complied report
InputStream compiledReportStream = context.getResourceAsStream(path
+ reportName + JASPER_EXTENSION);
try {
connection = dataSource.getConnection();
JasperRunManager.runReportToPdfStream(compiledReportStream, outputStream, new HashMap<String, Object>(), connection);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
ResponseBuilder restResponse = Response.ok();
restResponse.header("Content-Disposition",
"attachment; filename=firstSQLReport.pdf");
return restResponse.build();
}
The code runs fine but I do not get any download prompt, the pdf gets rendered on the browser instead. The response headers are as follows (on the browser):
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
Date: Wed, 21 Aug 2013 05:51:42 GMT
What's the reason that the code now fails to provide a download prompt? I am not an ace with HTTP but I guess this:
restResponse.header("Content-Disposition",
"attachment; filename=firstSQLReport.pdf");
is responsible for the download option. Its nowhere in the response although I did include it in the code. Please advice.
yes, you are right, Content-Disposition is the response header that you need to set to trigger the download action on the client browser.
i think you need to set the response headers first before writing to the response output stream.