Change the name of MultipartFile - spring-boot

I'm trying to change the name of MultipartFile.
I'm using MultipartFile on my controller to call rest service:
#PostMapping("/post")
public ResponseEntity<String> handleFileUpload(#RequestParam("file") MultipartFile file)
{
...
}
Have you please any idea about changing the OriginalFilename of the uploaded file ?.
Big thanks.

You can try the following code.
#PostMapping("/post")
public ResponseEntity<String> handleFileUpload(#RequestParam("file") MultipartFile file)
{
try {
String filename = "random_filename.pdf"; // Give a random filename here.
byte[] bytes = file.getBytes();
String insPath = <DIRECTORY PATH> + filename // Directory path where you want to save ;
Files.write(Paths.get(insPath), bytes);
return ResponseEntity.ok(filename);
}
catch (IOException e) {
// Handle exception here
}
}
You have to remember to add a random string to the file name. If you just hard code the file name, every time you upload a file, the previous file will be replaced.

You can achieve renaming of a file as below. To verify go the uploadDir and you will have a file with "renameTest".
You can append clientId + uploadTime to a filename to avoid the same filenames in database
#PostMapping(value = "/post")
public String renameMultipartFile(#RequestParam("file") MultipartFile file) {
String uploadDir = "yourPath";
String filename = "renameTest";
Path saveTO = Paths.get(uploadDir + filename);
try {
try {
Files.copy(file.getInputStream(), saveTO);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error : " + e.getMessage());
}
return "File uploaded successfully";
} catch (Exception e) {
e.printStackTrace();
return "Error : " + e.getMessage();
}
}

Related

file upload functionality fails on production server

I am using Spring Boot on Windows development environment with Java 1.8 open JDK 8.
File uploading functionality works fine on development environment. But, it does not work on production environment when I deploy the WAR file. My production environment has Apache tomcat 8.0.36, Java 1.8 open jdk 8, Ubuntu.
This is the web site :www.samslisting.com
Below is the spring Boot code.
#RequestMapping(value = "/SUB_CATEGORY_1_1_post", method = { RequestMethod.POST })
public ModelAndView categorypost(
#Valid #ModelAttribute("formData") SUB_CATEGORY_1_1 formData,
BindingResult bindingResult,
#RequestParam(value = "image",required = false) MultipartFile[] multipartFile,
HttpSession session, Model model) {
ModelAndView modelAndView = new ModelAndView();
boolean imageNotUploaded = false;
boolean unSupportedFileType = false;
for(int i=0;i<multipartFile.length;i++)
{
if(multipartFile[0].getOriginalFilename().equals(""))
{
imageNotUploaded = true;
}
if(!multipartFile[i].getOriginalFilename().equals("")) {
String fileName = multipartFile[i].getOriginalFilename();
String []fileNames = fileName.split("\\.");
int fileNamesLength = fileNames.length;
List <String > supportedFileTypes = new ArrayList<String >();
supportedFileTypes.add("apng");
supportedFileTypes.add("avif");
supportedFileTypes.add("gif");
supportedFileTypes.add("jpg");
supportedFileTypes.add("jpeg");
supportedFileTypes.add("jfif");
supportedFileTypes.add("pjpeg");
supportedFileTypes.add("pjp");
supportedFileTypes.add("png");
supportedFileTypes.add("svg");
supportedFileTypes.add("webp");
if(supportedFileTypes.contains(fileNames[fileNamesLength-1].toLowerCase()) )
{
}
else {
unSupportedFileType = true;
}
}
}
if (bindingResult.hasErrors() || imageNotUploaded||unSupportedFileType) {
HashMap<String, String> countrylist = null;
try {
countrylist = Common_List.getCountryList(dataSource.getConnection());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(imageNotUploaded) {
modelAndView.addObject("error", "Please upload image!");
}
if(unSupportedFileType) {
modelAndView.addObject("error1", "Please upload image of Type supported! "
+ " .apng, .avif, .gif, .jpg, .jpeg, .jfif, .pjpeg, .pjp, .png, .svg, .webp ");
}
modelAndView.addObject("countrylist", countrylist);
modelAndView.setViewName("SubCategory_1_1");
}else {
formData.setCATEGORY(SystemConstant.intCategory_1);
formData.setSUB_CATEGORY(SystemConstant.intSubCategory_1_1);
String caca = (String)session.getAttribute("USERID");
formData.setUSERID(Long.parseLong(caca));
formData = service.createOrUpdateUser(formData);
for(int i=0;i<multipartFile.length;i++)
{
if(!multipartFile[i].getOriginalFilename().equals(""))
{
String fileName = StringUtils.cleanPath(multipartFile[i].getOriginalFilename());
String rootPath = System.getProperty("catalina.home");
String uploadDir = System.getProperty("user.dir") + File.separator + "user-photos"+ File.separator + SystemConstant.intCategory_1+File.separator+ SystemConstant.intSubCategory_1_1+
File.separator+(String)session.getAttribute("USERID")+ File.separator+formData.getSUB_CATEGORY_1_1_ID();
Path uploadPath = Paths.get(uploadDir);
if (!Files.exists(uploadPath)) {
try {
Files.createDirectories(uploadPath);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
InputStream inputStream = multipartFile[i].getInputStream();
Path filePath = uploadPath.resolve(fileName);
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
IMAGES_1_1 image = new IMAGES_1_1();
image.setUSERID(formData.getUSERID());
image.setSUB_CATEGORY_1_1_ID(formData.getSUB_CATEGORY_1_1_ID());
image.setCATEGORY(SystemConstant.intCategory_1);
image.setSUB_CATEGORY(SystemConstant.intSubCategory_1_1);
image.setNAME(multipartFile[i].getOriginalFilename());
serviceImage.createOrUpdateImage(image);
} catch (IOException ioe) {
try {
throw new IOException("Could not save image file: " + fileName, ioe);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
modelAndView.setViewName("SamList");
}
return modelAndView;
}

EDIT IMAGE in Srping Boot Controller

In the edit section, I wrote how to make it upload the image
Thank you very much
#PostMapping("/save")
public String add(#ModelAttribute("category") Category category, RedirectAttributes ra,
#RequestParam("fileImage") MultipartFile multipartFile) throws IOException {
String fileName = StringUtils.cleanPath(multipartFile.getOriginalFilename());
category.setPhoto(fileName);
Category saveCategory = categoryService.save(category);
String uploadDir = "./category-logos/" + saveCategory.getId();
Path uploadPath = Paths.get(uploadDir);
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
try (InputStream inputStream = multipartFile.getInputStream()) {
Path filePath = uploadPath.resolve(fileName);
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new IOException("could not save upload file: " + fileName);
}
return "redirect:/category/list";
}
#GetMapping("/edit/{id}")
public String edit(Model model, #PathVariable(name="id")Long id) {
//`**`**`**enter code here**`**`**`
}

download csv using spring boot and apache commons

I have this below code for downloading CSV as an ajax button click, But the file is not downloading. Only showing the black new tab on the browser.
#RequestMapping(value = "/batch/download", method = RequestMethod.POST, produces = "text/csv")
#ResponseBody
public void downloadNGIBatchSelected(HttpServletResponse response) throws IOException {
List<String> ids = Arrays.asList("1312321","312313");
generateNewCustomerCSV(response.getWriter(),ids);
}
private void generateNewCustomerCSV(PrintWriter writer, List<String> ids){
String NEW_LINE_SEPARATOR = "\n";
//CSV file header
Object[] FILE_HEADER = {"Token Number",
"Token Expiry Date",
};
CSVPrinter csvPrinter = null;
try {
csvPrinter = new CSVPrinter(new BufferedWriter(writer), CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR));
//Create CSV file header
csvPrinter.printRecord(FILE_HEADER);
for (PolicyMap PolicyMap : policyMaps) {
List customerCSV = new ArrayList();
customerCSV.add(PolicyMap.getInsurancePolicy().getTokenNo());
try {
csvPrinter.printRecord(customerCSV);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.flush();
writer.close();
csvPrinter.close();
} catch (IOException e) {
System.out.println("Error while flushing/closing fileWriter/csvPrinter !!!");
e.printStackTrace();
}
}
}
You have set the content type in #RequestMapping annotation. But it is not going to work in the case when response is being written using HttpServletResponse. In this case, instead of spring, HttpServletResponse is writing the response that's why you have to set the response type in the response before getting the writer.
response.setContentType ("application/csv");
response.setHeader ("Content-Disposition", "attachment; filename=\"nishith.csv\"");

Uploading, modifying and download the same file in memory

I have to create an application that allows the user upload a specific Excel file. Sumarizing, the system needs to receive the file, write something in a specific cell and return the same file modificated to the view, then, the user can download this new file.
I'm using Apache POI for modify the excel file, but I don't know how to return this file to the view.
Upload view:
<form method="POST" enctype="multipart/form-data" th:action="#{/pessoa/lote}">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>
Controller: Here I don't know what I need to do, I call a method named "consultaLote" from a Service who is named "ConsultaPessoaService".
#RequestMapping(value = "/lote", method = RequestMethod.POST)
public String handleFileUpload(#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
try {
cpService.consultaLote(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
In the service, I can read and edit the file, then its generated a FileOutputStream. At this time I don't know how to continue, I need to return the file to the view using the controller, but I don't know how:
#Service
public class ConsultaPessoaService {
public FileOutputStream consultaLote(MultipartFile file) throws IOException {
DataFormatter formatter = new DataFormatter();
File convFile = new File(file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
FileInputStream inputStream = new FileInputStream(convFile);
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(0);
Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) {
Row nextRow = iterator.next();
System.out.println(formatter.formatCellValue(nextRow.getCell(3)));
nextRow.getCell(3).setCellValue("test");
}
FileOutputStream outputStream = new FileOutputStream("arquivot.xlsx");
workbook.write(outputStream);
workbook.close();
outputStream.flush();
outputStream.close();
return outputStream;
}
}
You should return a byte array from consultaLote method. Method return type will be byte[] because you need this byte array to write the httpservlet outputstream.
public byte[] consultaLote(MultipartFile file) throws IOException {
//whatever changes you want, do it here. I am going to converting part
ByteArrayOutputStream baos = new ByteArrayOutputStream();
workbook.write(baos);
// before returning you can close your your ByteArrayOutputStream
//baos.close();
return baos.toByteArray();
}
Now comes to your controller. We write the byte array to OutputStream from HttpservletResponse.
#RequestMapping(value = "/lote", method = RequestMethod.POST)
public String handleFileUpload(#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes,HttpServletResponse response) {
byte[] fileBytes = null;
String reportName="yourReportName";
try {
fileBytes = cpService.consultaLote(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(fileBytes !=null){
response.setHeader("Content-Disposition", "attachment; filename=" + reportName + ".xls");
response.setContentType("application/xls");
response.getOutputStream().write(fileBytes);
response.getOutputStream().flush();
}
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
Hope this will help.

File upload with in Spring MVC without adding any additional parameter in controller method

I am using spring boot 2. My new task is file uploading. I already did it. But I am asked to do it without adding a additional parameter to controller method like #RequestParam("files") MultipartFile files[]. I want to get this from request instead of adding this parameter.
How can I solve this?
I am adding my current code following.
#RequestMapping(value="/uploadMultipleFiles", method=RequestMethod.POST)
public #ResponseBody String handleFileUpload( #RequestParam("files") MultipartFile files[]){
try {
String filePath="c:/temp/kk/";
StringBuffer result=new StringBuffer();
byte[] bytes=null;
result.append("Uploading of File(s) ");
for (int i=0;i<files.length;i++) {
if (!files[i].isEmpty()) {
bytes = files[i].getBytes();
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath+files[i].getOriginalFilename())));
stream.write(bytes);
stream.close();
result.append(files[i].getOriginalFilename() + " Ok. ") ;
}
else
result.append( files[i].getOriginalFilename() + " Failed. ");
}
return result.toString();
} catch (Exception e) {
return "Error Occured while uploading files." + " => " + e.getMessage();
}
}
You can get files from HttpRequest:
#RequestMapping(value="/uploadMultipleFiles", method=RequestMethod.POST)
public String handleFileUpload(HttpRequest request){
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> yourFiles = multipartRequest.getFileMap();
return "All is Ok!";
}
My sample code.
#RequestMapping(value = "/multiple/upload", method = RequestMethod.POST)
public #ResponseBody String test(#RequestParam(value = "files[]") List<MultipartFile> files,
HttpServletRequest req) {
MultipartFileWriter writer = new MultipartFileWriter();
String folderPath = "/file/";
for (MultipartFile file : files) {
writer.writeFile(file, folderPath, req);
}
return "success";
}

Resources