Spring Boot - Upload file to server - java

The code belows prompts a user to select a file on his local repository, enter some input fields and then upload the file to a server. Currently, it will store it in a /tmp folder, as it is created by createTempFile. The file is successfully created, and an object is created with a reference to that file as needed by the business case. Yay!
However, I want to store all files in a seperate and organizable folder like "/uploadedFiles" on the server repository.
I have tried several things, from creating an empty file on the repository folder and then attempting an overwrite on to it, to just copying the uploaded file to the folder. None of what seemed to be easy fixes worked so far, unless I missed something obvious (which I probably did).
The files created all have a long sequence of numbers after the file extension in their names, like "testfile.xls1612634232432"; is this from the buffer of the inputstream?
The code below is how it currently works, with just writing the uploaded file to a temp file in the /tmp directory. I need to get it to any other directory of my choosing, and then eligibly pass it to the object constructor.
The method begins at newTestUpload.
#MultipartConfig
#RestController
#RequestMapping(value = "/Teacher", produces = "text/html;charset=UTF-8")
public class Teacher {
TestController testcont = TestController.getInstance();
#GetMapping("")
#ResponseBody
public String homePage(#RequestParam(value = "file", required = false) String name, HttpServletRequest request,
HttpServletResponse response) {
StringBuilder sb = new StringBuilder();
sb.append("<p> <a href='/Teacher/NewTest'>New Test upload</a></p>\n"
+ "<p><a href='/SelectTest'>Select Test File</a> <button type='button'>Send Test</button></p>"
+ "\n \n \n" + "<p><a>Current Test for students:</a>\n <a href='/getCurrentTest'></a></p>");
return sb.toString();
}
#PostMapping
#RequestMapping("/NewTest")
#ResponseBody
public String newTestUpload(HttpServletRequest request, HttpServletResponse response) {
StringBuilder sb = new StringBuilder();
try {
if (!request.getParameterNames().hasMoreElements()) {
sb.append("<p><form action='' method='post' enctype='multipart/form-data'>"
+ "<label>Enter file</label><input type='file' name='file'>"
+ "<button type='submit'>Upload</button></p>"
+ "<p><form action='/testName'>Test Name: <input type='text' name='name' value=''></p>"
+ "<p><form action='/addInfo'>Comment: <input type='text' comment='comment' value=''></p>"
+ "<p>Answer 1: <input type='text' Answer='answer1' value=''></p>"
+ "<p>Answer 2: <input type='text' Answer='answer2' value=''></p>"
+ "</form>"
+ "<a href='/Teacher'>Back</a>\n");
return sb.toString();
} else if (request.getParameter("name") != "" && request.getParameter("comment") != ""
&& request.getParameter("answer1") != "" && request.getParameter("answer2") != "") {
try {
// This is where the magic happens
Part filePart = request.getPart("file");
String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
InputStream fileContent = filePart.getInputStream();
byte[] buffer = new byte[fileContent.available()];
fileContent.read(buffer);
File testExcel = File.createTempFile(fileName, "", null);
OutputStream outStream = new FileOutputStream(testExcel);
outStream.write(buffer);
// double ans1 =
// Double.parseDouble(request.getParameter("answer1"));
// double ans2 =
// Double.parseDouble(request.getParameter("answer2"));
Test test = new Test(testExcel, request.getParameter("name"), request.getParameter("comment"),
request.getParameter("answer1"), request.getParameter("answer2"));
testcont.addTest(test);
testExcel.deleteOnExit();
outStream.close();
sb.append("New test uploaded!<br/>\n<a href='/Teacher'>Back</a>\n" + testExcel.getPath()
+ "<p>_________</p>" + test.getFile().getPath());
return sb.toString();
} catch (Exception e) {
sb.append("<h1>Couldnt insert test</h1>\n" + e.getMessage() + e.getStackTrace() + e.getCause());
response.setStatus(HttpServletResponse.SC_OK);
e.printStackTrace();
return sb.toString();
}
} else {
sb.append("failed<br/>\n<a href='/Teacher/NewTest'>Back</a>\n");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return sb.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}

Instead of creating a temp file, create file in the directory that you want to create.
OutputStream outStream = new FileOutputStream(new File("<fileName>"));
If you want to create file first without data. you can use below code, it will create directory as well if not already created:
public static void saveToFile(String folderPath, String fileName) throws IOException {
File directory = new File(folderPath);
if (!directory.exists() && !directory.mkdirs()) {
throw new IOException("Directory does not exist and could not be created");
}
String filePath = folderPath + File.separator + fileName;
File theFile = new File(filePath);
if (!theFile.exists()) {
try {
theFile.createNewFile();
} catch (IOException e) {
throw new IOException("Facing issues in creating file " + filePath, e);
}
}
}

File testExcel = File.createTempFile(fileName, "", null);
replaced with:
File testExcel = new File("/tests/", fileName);
testExcel.getParentFile().mkdirs();
did the trick! Works like a charm now.

Related

File size limit at aws s3 file upload

I am currently implementing aws s3 file upload. Among the implementation features, we are trying to make uploads less than 300KB. The file size is written in the application.yml file.
However, when comparing the file size after taking it out from the source, if you compare it like file.getsize() >= maxSize, an error occurs because of the data type difference. How should the logic be structured?
My code
#RequiredArgsConstructor
#Service
public class FileUploadService {
private final UploadService s3Service;
public String uploadImage(MultipartFile file) {
String original = createFileName(file.getOriginalFilename());
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(file.getContentType());
objectMetadata.setContentLength(file.getSize());
try (InputStream inputStream = file.getInputStream()) {
s3Service.uploadFile(inputStream, objectMetadata, original);
} catch (IOException e) {
throw new IllegalArgumentException(String.format("file Error!! (%s)", file.getOriginalFilename()));
}
System.out.println("file upload");
System.out.println("fila name : ": + file.getOriginalFilename());
System.out.println("file type : " + getFileType(file));
System.out.println("file size : " + getFileSize(file) + " Bytes");
System.out.println("-----------------------------------------");
return "File Upload Success! , FileName : " + file.getOriginalFilename()
+ " , File Size : " + getFileSize(file) + " Bytes";
}
private String createFileName(String originalFileName) {
return UUID.randomUUID().toString().concat(getFileExtension(originalFileName));
}
private String getFileExtension(String fileName) {
try {
return fileName.substring(fileName.lastIndexOf("."));
} catch (StringIndexOutOfBoundsException e) {
throw new IllegalArgumentException(String.format("잘못된 형식의 파일 (%s) 입니다", fileName));
}
}
private long getFileSize(MultipartFile file) {
return file.getSize();
}
private String getFileType(MultipartFile file) {
return file.getContentType();
}
}
application.yml
spring:
profiles:
include:
- aws
- credentials
servlet:
multipart:
max-file-size: 300KB
max-request-size: 1MB
I don't know right now either, so I'll try to keep trying by posting a question and searching!! I think we still have to keep learning.
Thank you
I wrote and tried my own logic, but I couldn't figure it out, so I wrote a question

Downloading excel file from spring java causing file to corrupt

I am trying to call this method from my filter and i am successfully able to download the excel but after the download when i open the excel it shows that it is corrupted but when i see the file on server files opens fine without any error.
Excel error : excel cannot open the file "filename" because the file format or file extension is not valid.
public static void downloadFileFromServer(HttpServletResponse response, String sourceFile,
Boolean isFilenameHavingTimestamp,Boolean deleteTempFile) throws IOException, Exception {
logger.debug("Inside ServiceUtils.downloadFileFromServer()");
// splitting serverPath and fileName
String serverHomeDirectory[] = sourceFile.split("\\\\|/");
String fileName = serverHomeDirectory[serverHomeDirectory.length - 1];
fileName = URLDecoder.decode(fileName, "UTF-8");
if (Boolean.TRUE.equals(isFilenameHavingTimestamp)) {
fileName = removeTimestampFromFilename(fileName);
}
response.setContentType("application/octet-stream");
response.addHeader("content-disposition", "attachment; filename=\"" + fileName + "\"");
try (ServletOutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(sourceFile);) {
int octet = 0;
while ((octet = in.read()) != -1) {
out.write(octet);
}
} catch (Exception e) {
logger.error("Exception in ServiceUtils.downloadFileFromServer(): ", e);
throw new Exception(ExceptionMessage.ERROR_DOWNLOAD_EXCEL_FILE);
} finally {
// check if file needs to be deleted after download
/*if(deleteTempFile)
deleteTempFile(sourceFile);*/
}
}
Problem was that the response already had a string and code was writing the file appending the existing response in the buffer.
Solved the problem by adding below code before setContentType()
response.reset();

Javafx save textField to a text file

I have this code for saving to a text file however, I can't seem to find a way to make it save to not the user.home folder but to another folder on my hard drive. I searched in many places but couldn't really find anything that could help me.
It works with the user.home setting but if I try to change it, it doesn't. The program, when executed, comes up with Source not found.
saveBtn.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
Object source = event.getSource();
String s = null;
//Variable to display text read from file
if (_clickMeMode) {
FileOutputStream out = null;
try {
//Code to write to file
String text = titleField.getText();
byte b[] = text.getBytes();
String outputFileName = System.getProperty("user.home"
+ File.separatorChar+"home")
+ File.separatorChar + "Movies2.txt";
out = new FileOutputStream(outputFileName);
out.write(b);
out.close();
//Clear text field
titleField.setText("");
}catch (java.io.IOException e) {
System.out.println("Cannotss text.txt");
} finally {
try {
out.close();
} catch (java.io.IOException e) {
System.out.println("Cannote");
}
}
}
else
{
//Save text to file
_clickMeMode = true;
}
window.setTitle("Main Screen");
window.setScene(mainScreen);
}
});
Your file name is incorrectly assigned:
String outputFileName = System.getProperty("user.home"
+ File.separatorChar+"home")
+ File.separatorChar + "Movies2.txt";
You are passing a string of the form "user.home/home" to System.getProperty().
Since there is no such property, this will return null.
Then you concatenate this with /Movies2.txt, so outputFileName will be something like null/Movies2.txt.
(A simple System.out.println(outputFileName) will confirm this.)
Instead of building the filename by hand like this, you should use a higher-level API to do it. E.g.:
Path outputFile = Paths.get(System.getProperty("user.home"), "home", "Movies2.txt");
OutputStream out = Files.newOutputStream(outputFile);
out.write(b);
If you also need (or might need) to create the directory, you can do
Path outputDir = Paths.get(System.getProperty("user.home"), "home");
Files.createDirectories(outputDir);
Path outputFile = outputDir.resolve("Movies2.txt");
OutputStream out = Files.newOutputStream(outputFile);
out.write(b);

Correct way of sending and getting files Spring

Whats the correct way of sending and getting files and save it to a folder?
I am sending a post from Postman with body form-data: 2 keys 'uploadfile' each with one zip.
This code gets only one zip and save it, ignoring the second zip.
How can I implement it to save both files?
Also. Should I send 2 files in one key? or each file in separated keys?
#RequestMapping(value = "/api/uploadFile", method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<?> uploadFile(
#RequestParam("uploadfile") MultipartFile uploadfile) {
try {
// Get the filename and build the local file path (be sure that the
// application have write permissions on such directory)
String filename = uploadfile.getOriginalFilename();
String directory = "C://Develop//files";
String filepath = Paths.get(directory, filename).toString();
filenameZip = "c:/Develop/files/"+filename;
directoryZip = "c:/Develop/files";
// Save the file locally
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(filepath)));
stream.write(uploadfile.getBytes());
stream.close();
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
// unzip(filenameZip, directoryZip);
return new ResponseEntity<>(HttpStatus.OK);
} // method uploadFile
Postman Log:
var data = new FormData();
data.append("uploadfile", "pasta1.zip");
data.append("uploadfile", "pasta2.zip");
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "http://localhost:8080/api/uploadFile");
xhr.setRequestHeader("authorization", "Basic b3BlcmF0aW9uczpvcGVyYXRpb25z");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("postman-token", "e7b6fcae-4a49-de34-ba7c-efd412fb244a");
xhr.send(data);
you can make your service accept array of multipart file then you can send to it as much as you want of files to upload it and here is an exmaple
#RequestMapping(value="/multipleSave", method=RequestMethod.POST )
public #ResponseBody String multipleSave(#RequestParam("file") MultipartFile[] files){
String fileName = null;
String msg = "";
if (files != null && files.length >0) {
for(int i =0 ;i< files.length; i++){
try {
fileName = files[i].getOriginalFilename();
byte[] bytes = files[i].getBytes();
BufferedOutputStream buffStream =
new BufferedOutputStream(new FileOutputStream(new File("F:/cp/" + fileName)));
buffStream.write(bytes);
buffStream.close();
msg += "You have successfully uploaded " + fileName +"<br/>";
} catch (Exception e) {
return "You failed to upload " + fileName + ": " + e.getMessage() +"<br/>";
}
}
return msg;
} else {
return "Unable to upload. File is empty.";
}
}
}
and for the key part you can send all files with the same key

How to upload file using java ?

Hello i m trying to upload file using java file.. but i don't get it.. i get file size=0 i'm providing here my java code. tell me why i cant upload on particular folder. i want to store my file in particular folder. i am trying to get file size, file name but i got the null value where am i wrong please tell me.
public void updateTesti(ActionRequest actionRequest,ActionResponse actionResponse) throws IOException, PortletException
{
//image upload logic
String folder_for_upload =(getPortletContext().getRealPath("/"));
//String folder=actionRequest.getParameter("uploadfolder");
realPath=getPortletContext().getRealPath("/");
logger.info("RealPath is" + realPath);
logger.info("Folder is :" + folder_for_upload);
try
{
logger.info("Admin is try to upload");
UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(actionRequest);
if (uploadRequest.getSize("fileName") == 0) {
SessionErrors.add(actionRequest, "error");
}
String sourceFileName = uploadRequest.getFileName("fileName");
File uploadedFile = uploadRequest.getFile("fileName");
System.out.println("Size of uploaded file: " + uploadRequest.getSize("fileName"));
logger.info("Uploded file name is: " + uploadRequest.getFileName("fileName"));
String destiFolder=("/home/ubuntu/liferay/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/webapps/imageUpload-portlet/image");
String newsourcefilename = (uploadRequest.getFileName("fileName"));
File newFile = new File(destiFolder +"/"+ newsourcefilename);
logger.info("New file name: " + newFile.getName());
logger.info("New file path: " + newFile.getPath());
InputStream in = new BufferedInputStream(uploadRequest.getFileAsStream("fileName"));
FileInputStream fis = new FileInputStream(uploadedFile);
FileOutputStream fos = new FileOutputStream(newFile);
byte[] bytes_ = FileUtil.getBytes(in);
int i = fis.read(bytes_);
while (i != -1) {
fos.write(bytes_, 0, i);
i = fis.read(bytes_);
}
fis.close();
fos.close();
Float size = (float) newFile.length();
System.out.println("file size bytes:" + size);
System.out.println("file size Mb:" + size / 1048576);
logger.info("File created: " + newFile.getName());
SessionMessages.add(actionRequest, "success");
}
catch (FileNotFoundException e)
{
System.out.println("File Not Found.");
e.printStackTrace();
SessionMessages.add(actionRequest, "error");
}
catch (NullPointerException e)
{
System.out.println("File Not Found");
e.printStackTrace();
SessionMessages.add(actionRequest, "error");
}
catch (IOException e1)
{
System.out.println("Error Reading The File.");
SessionMessages.add(actionRequest, "error");
e1.printStackTrace();
}
}
You need to do this to upload small files < 1kb
File f2 = uploadRequest.getFile("fileupload", true);
They are stored in memory only. I have it in my catch statement incase I get a null pointer - or incase my original file (f1.length) == 0
I have executed your code.It is working as per expectation.There might be something wrong in your jsp page.I am not sure but might be your name attribute is not same as the one which you are using in processAction(assuming that you are using portlet).Parameter is case sensitive,so check it again.
You will find more on below link.It has good explanation in file upload.
http://www.codeyouneed.com/liferay-portlet-file-upload-tutorial/
I went through a file upload code, and when i implement that in my local system what i got is, portlet is saving the file i upload in tomcat/webbapp/abc_portlet_project location, what i dont understand is from where portlet found
String folder = getInitParameter("uploadFolder");
String realPath = getPortletContext().getRealPath("/");
System.out.println("RealPath" + realPath +"\\" + folder); try {
UploadPortletRequest uploadRequest =
PortalUtil.getUploadPortletRequest(actionRequest);
System.out.println("Size: "+uploadRequest.getSize("fileName"));
if (uploadRequest.getSize("fileName")==0)
{SessionErrors.add(actionRequest, "error");}
String sourceFileName = uploadRequest.getFileName("fileName"); File
file = uploadRequest.getFile("fileName");
System.out.println("Nome file:" +
uploadRequest.getFileName("fileName")); File newFolder = null;
newFolder = new File(realPath +"\" + folder);
if(!newFolder.exists()){ newFolder.mkdir(); }
File newfile = null;
newfile = new File(newFolder.getAbsoluteFile()+"\"+sourceFileName);
System.out.println("New file name: " + newfile.getName());
System.out.println("New file path: " + newfile.getPath());
InputStream in = new
BufferedInputStream(uploadRequest.getFileAsStream("fileName"));
FileInputStream fis = new FileInputStream(file); FileOutputStream fos
= new FileOutputStream(newfile);

Categories

Resources