Spring boot Content-Disposition filename in Russian - spring

the problem with downloading a file from the server, the file name may contain Russian text, when downloading it substitutes ??????? instead of Russian letters, and the download breaks, a file without an extension named 1 is downloaded. How do I fix it?
#GetMapping("/download/{id}")
public ResponseEntity<byte[]> getFile(#PathVariable Long id) {
File file = fileStorageService.getFile(id);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
.contentType(MediaType.valueOf("application/docx"))
.body(file.getData());
}
Question number two, is there a dynamic way to specify the content-type depending on the file extension?

ContentDisposition contentDisposition = ContentDisposition.builder("attachment")
.filename(file.getName(), StandardCharsets.UTF_8)
.build();
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString())
.contentType(MediaType.valueOf(file.getType()))
.body(file.getData());

Related

How can I configure the Content-Length in the header?

I have a code that generates a csv. And I want to have Content-Length in the header for a functionality that I want to do from the frontend.
I don't know how to add it, any idea
#GetMapping("/report-csv")
public ResponseEntity<Resource> getReportCSV() {
InputStreamResource file = new InputStreamResource(generate_report_csv.port_list());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, CSV_HEADER)
.contentType(MediaType.parseMediaType(CSV_MEDIA_TYPE))
//.contentLength()
.cacheControl(CacheControl.noCache())
.body(file);
}

WebClient - Flux<DataBuffer> - Content not getting created

I am trying to download a file form remote location using Spring WebClient and when I does that , the file is getting created but the content is not getting created. The File still remain 0KB. Any help ,
Flux<DataBuffer> dataBuffer = emailTemplateWebclient
.get()
.uri(gitHubEmailTemplateURL + fileName + ".html")
.retrieve()
.bodyToFlux(DataBuffer.class);
dataBuffer.subscribe();
DataBufferUtils
.write(dataBuffer, destination, StandardOpenOption.CREATE).block();

Spring REST file download unable to set header content-type attachment

I have a Springboot REST application that downloads files from a given directory.
The downloads can be any file file and have any format, and I want to use the original filename as the filename of the downloaded file.
I used the code below to set the filename in the header, and add the header to the response:
#RestController
#RequestMapping("/downloads")
public class DownloadCsontroller {
...
#GetMapping
public void downloadSingleFile(#RequestParam("file") String filename, HttpServletResponse response) throws IOException {
String filepath = m_attachmentPathLocation + File.separator + filename;
File file = new File(filepath);
String contentType = getContentType(file);
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(contentType);
response.setHeader("Content-Disposition:", "attachment;filename=\"" + file.getName() + "\"");
...
}
...
}
Tested using both "Content-Disposition" and "Content-Disposition:" in setHeader().
Almost everything works (file types), except for PDF, ZIP, RAR, EXE, etc.
Any files (types) not on the list can be downloaded with the desired filenames.
But when any of the file download (PDF, ZIP, RAR, EXE, etc)... it seems it continuously loads like forever... and I cannot even see any request sent in POSTMAN, inspector, firebug, etc.
If I comment out:
//response.setHeader("Content-Disposition:", "attachment;filename=\"" + file.getName() + "\"");
It would work, but the filename would be set to the name of the request mapping. which in this case is "downloads".
I have seen lots of samples that uses "Content-Disposition" header to change the attachment filename... but it seems it fails on these file types.
I have no configurations yet, and it is kinda weird since in most samples I searched... this should be running or working.
TIA
Please add #GetMapping(produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
and instead of returning direct file try to return stream.
Also make a note that "Content-Disposition:" header will not work if the requesting app IP & Port number is different from server app IP & Port number.
Things would work If you can alter the code a bit, by setting all header values using org.springframework.http.HttpHeaders class.
Now looking at your code, i suspect you trying to expose an API that allows to download a multipart File.
I would suggest you not to use HttpServletResponse Class to set the Content- Dispositionheader but use HttpHeaders class. Below is the reformatted code
#RestController
public class DownloadCsontroller {
#GetMapping(value="/downloads")
public ResponseEntity<Object> downloadSingleFile(#RequestParam("file")
String filename) throws IOException {
String filepath = m_attachmentPathLocation + File.separator + filename;
File file = new File(filepath);
String contentType = getContentType(file);
/* response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(contentType);
response.setHeader("Content-Disposition:", "attachment;filename=\""
+ file.getName() + "\"");
*/
// Here is the below Code you need to reform for Content-
//Disposition and the remaining header values too.
HttpHeaders headers= new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename
=whatever.pdf");
headers.add("Content-Type",contentType);
// you shall add the body too in the ResponseEntity Return object
return new ResponseEntity<Object>(headers, HttpStatus.OK);
}
}

Uploading more than one image

Dear All,
Working on Spring MVC. I want to upload more than one images from the client. How to achieve it. I know how to handle the multipart form data for single image. But now I am expecting some data with some images from the client.
Any help or url that will help me.
Thanks,
Op
Image is also a file. Whether you would be storing it in database / in file system but it is still a file.
In spring MVC, you could do as shown in the below link:
http://viralpatel.net/blogs/spring-mvc-multiple-file-upload-example/
Here are the code i tried and it is working fine at my end.
//Handle multiple images
#RequestMapping(method = RequestMethod.POST, value="upload", consumes=MediaType.MULTIPART_FORM_DATA_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody JSONResponse uploadImages(HttpServletRequest req)
throws Exception {
try{
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) req;
Set set = multipartRequest.getFileMap().entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
String fileName = (String)me.getKey()+"_"+System.currentTimeMillis();
MultipartFile multipartFile = (MultipartFile)me.getValue();
System.out.println("Original fileName - " + multipartFile.getOriginalFilename());
System.out.println("fileName - " + fileName);
saveImage(fileName, multipartFile);
}
}
catch(Exception e){
e.printStackTrace();
}
return new JSONResponse();
}

Why does Firefox trim the response file name?

The following code accesses a helper method which creates and returns an EPPlus ExcelPackage, then returns the package to the browser:
public ActionResult DownloadMatrixExcel(int projectId)
{
try
{
// Get project details
var project = (from p in db.Projects
where p.ProjectId == projectId
select new
{
companyName = p.Company.Name,
projectName = p.Name
}).Single();
// Must append file type to file download responses
var fileName = project.projectName + "-" + project.companyName + "-" + DateTime.Now.ToString("yyyyMMdd", CultureInfo.InvariantCulture) + ".xlsx";
// Configure response
Response.Clear();
Response.BufferOutput = false;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
// Create and populate excel package
var matrixSpreadsheet = ExcelHelper.BuildMatrixExcel(projectId);
matrixSpreadsheet.SaveAs(Response.OutputStream);
}
catch (Exception e)
{
return Content("Error: " + e.Message);
}
// Download okay - No ViewResult
return new EmptyResult();
}
Works fine in every browser I have tested but FireFox 18.0.1 (have yet to test other FF versions) trims the file name at the first space, so "someproject - somecompany - thedate" is just "someproject". I can do a Replace and remove spaces but this makes some file names look a bit odd. File extension seems to be intact and no other issues but wondered if anyone could offer an explanation or fix?
You should place the filename between quote characters ("filename").
Okay, found the answer here while researching another issue: File Download issue in FireFox only
Response.AddHeader("Content-Disposition",
string.Format("attachment; filename = \"{0}\"",
System.IO.Path.GetFileName(FileName)));
This will also give the file the correct content type when you choose to save rather than open in browser in FireFox.

Resources