Correct way of sending and getting files Spring - java

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

Related

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();

Spring Boot - Upload file to server

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.

InputStream is null when i try to download gpx file from server and parse it

The problem is that downloading gpx file through http get request (retrofit) on Android device, parse it and show the route on google maps.
I have done first thing using retrofit and saved the file like "cyclingRoute.gpx" to downloads file on device like this:
NetworkBuilder.getAppNetwork().getRoute(routeId).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.e("###########", "API SUCCESS");
try {
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file = new File(path, "cyclingRoute.gpx");
FileOutputStream fileOutputStream = new FileOutputStream(file);
IOUtils.write(response.body().bytes(), fileOutputStream);
parseRoute(file);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("###########", "API FAILS" + t.getMessage());
}
});
for the parsing part i used a third party library from android arsenal: https://github.com/ticofab/android-gpx-parser
GPXParser mParser = new GPXParser();
Gpx parsedGpx = null;
try {
InputStream is = getClass().getResourceAsStream(file.getName());
parsedGpx = mParser.parse(is);
} catch (IOException | XmlPullParserException e) {
// do something with this exception
e.printStackTrace();
}
if (parsedGpx == null) {
// error parsing track
} else {
// do something with the parsed track
List<Track> tracks = parsedGpx.getTracks();
for (int i = 0; i < tracks.size(); i++) {
Track track = tracks.get(i);
Log.d(TAG, "track " + i + ":");
List<TrackSegment> segments = track.getTrackSegments();
for (int j = 0; j < segments.size(); j++) {
TrackSegment segment = segments.get(j);
Log.d(TAG, " segment " + j + ":");
for (TrackPoint trackPoint : segment.getTrackPoints()) {
Log.d(TAG, " point: lat " + trackPoint.getLatitude() + ", lon " + trackPoint.getLongitude());
}
}
}
}
When i run the code "InputStream is" being null and throws an exception. Where am i doing wrong?
Instead of this line -> InputStream is = getClass().getResourceAsStream(file.getName());
i tried this one as well -> InputStream in = getAssets().open("cycylingRoute.gpx");
and that throws an exception telling that no directory or file is found.
and also I am planing to collect all the tracks in json and pass it to google maps (if it is a correct way to do it). Any suggestions on that?
I would really appriciate if you help meee!!
Thanks.
In InputStream in = getAssets().open("cycylingRoute.gpx"); where do you define "Downloads"?
You are using File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); to store a file.

Java File Download - Downloaded file size is always zero Kb

I have written a java controller which handles any download request from the server. My files are present in the server however I am getting 0 kB file downloaded every time. The file is getting downloaded but the size is always 0 Kb. Please help me. Here is my code -
#RequestMapping(value="/downloadFile/{docId}")
public void getDownloadFile(#PathVariable(value = "docId") Integer docId, HttpServletResponse response) throws Exception {
String userName = getUserName();
try {
DocVault documentsVault = documentsVaultRepository.findDocumentAttachment(docId);
String fileName = documentsVault.getDocumentName();
int customerId = documentsVault.getCustomerId();
Map<Integer, String> customerInfo = cspUtils.getCustomersInfo(userName);
Set<Integer> customerIds = customerInfo.keySet();
for (int custId : customerIds) {
if (custId == customerId) {
String path = env.getProperty("doc.rootfolder") + File.separator + documentsVault.getFileName();
service.downloadFile(fileName, path, response);
} else {
logger.info("Customer not linked to user");
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
Implementation -
public void downloadFile(String fileName, String path, HttpServletResponse response) {
try {
File downloadFile = new File(path);
FileInputStream inputStream = new FileInputStream(downloadFile);
response.setContentLength((int) downloadFile.length());
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
// get output stream of the response
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
// write bytes read from the input stream into the output stream
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I am not getting any exceptions. Please help.
Thank you in advance.
response.setContentLength((int) downloadFile.length());
Remove this. The container will set it automatically.
int bytesRead = -1;
You don't need to initialize this variable. It gets assigned in the very next line.
Thank you for your help. What I figured out was there was a problem with my Content Disposition header. I was passing only the file name without extension. When I passed the full file name then it worked perfectly. Size and Extension of the file were proper.

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