Spring Boot | Upload an image to relative path in resources - spring

I get "System can't find the path specified." when I try to upload an image to project folder inside resources.
Here is my project structure:
|Project
|src
|main
|resources
|META-INF.resources
|images
Project Structural Hierarchy can be seen here in the image format.
I have defined the path as
String path = "\\resources\\images\\" + imageName; File file = new File(path );
try {
InputStream is = event.getFile().getInputstream();
OutputStream out = new FileOutputStream(path );
byte buf[] = new byte[1024];
int len;
while ((len = is.read(buf)) > 0)
out.write(buf, 0, len);
is.close();
out.close();
} catch (Exception e) {
System.out.println(e);
}
What can be the exact path to images folder under META-INF.resources directory?

The following should work fine:
//App.java
String path = "\\META-INF.resources\\images\\" + imageName;
InputStream is = App.class.getClassLoader().getResourceAsStream(
path);
In a nut shell, use "getClassLoader().getResourceAsStream()" instead of FileInputStream or FileOutputStream.

Following worked for me.
In application.properties I defined my path string as:
image.path = src/main/resources/META-INF/resources/images/uploads/
Here is my uploadImage function in a class file.
#Autowired
private Environment environment;
public String uploadImg(FileUploadEvent event, String imagePrefix) {
String path = environment.getProperty("image.path");
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
String name = fmt.format(new Date())
+ event.getFile().getFileName().substring(
event.getFile().getFileName().lastIndexOf('.'));
name = String.format("%s%s" ,imagePrefix ,name );
String finalPath = String.format("%s%s" ,path ,name);
System.out.println("image is going to save # " +finalPath);
File file = new File(finalPath).getAbsoluteFile();
try {
InputStream is = event.getFile().getInputstream();
OutputStream out = new FileOutputStream(file);
byte buf[] = new byte[1024];
int len;
while ((len = is.read(buf)) > 0)
out.write(buf, 0, len);
is.close();
out.close();
} catch (Exception e) {
System.out.println(e);
}
return name;
}
I am not sure whether it will work at production or not. Basically I get absolute path of the project and then append my relatively extracted path. Correct me if I am wrong.

Related

Send multiple files from angular typescript to spring and return as zip folder for downloading?

I want to send multiple files in an array to spring and create a zip folder for downloading
UploadController:
#Autowired
StorageService storageService;
#PostMapping("/upload")
public ResponseEntity<ResponseMessage> uploadFiles(#RequestParam("files") MultipartFile[] files) {
String message = "";
try {
storageService.zip(files);
message = "Uploaded the files successfully";
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
} catch (Exception e) {
message = "Fail to upload files!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
}
}
StorageService
public void zip(MultipartFile[] files) {
List<Path> filepaths = new ArrayList();
for (MultipartFile file : files) {
Path filepath = Paths.get("my/tmp/dir", file.getOriginalFilename());
filepaths.add(filepath);
try (OutputStream os = Files.newOutputStream(filepath)) {
os.write(file.getBytes());
}
}
File zip = new File("path/to/my/zip");
try { zip.createNewFile(); }
FileOutputStream output = null;
try { output = new FileOutputStream(zip); }
ZipOutputStream out = new ZipOutputStream(output);
try {
for (Path filepath : filepaths) {
File f = new File(filepath);
FileInputStream input = new FileInputStream(f);
ZipEntry e = new ZipEntry(f.getName());
out.putNextEntry(e);
byte[] bytes = new byte[1024];
int length;
while((length = input.read(bytes)) >= 0) {
out.write(bytes, 0, length);
}
input.close();
}
out.close();
output.close();
}
}

lose of ZLIB inputstream fails when using try with resources

i have function for decompressing zips with multiple entries. Sometimes an exception is catched that states "Unexpected end of ZLIB Input stream". In my opinion it is not possible because i am using try with resrsources.
private boolean decompress(final Path blf) {
final String pathToZip = blf.getParent().toString();
final byte[] buffer = new byte[8192];
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(blf.toFile()))) {
//We will unzip files in this folder
if (!Files.exists(Paths.get(pathToZip))) {
Files.createDirectory(Paths.get(pathToZip));
}
ZipEntry entry = zipInputStream.getNextEntry();
final Path pathToFile = Paths.get(pathToZip + "\\" + entry.getName());
//Faster procedure if the file already exists
if (Files.exists((pathToFile))) {
loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
"File already exists, skipping" + pathToFile));
return true;
}
//Iterate over entries
while (entry != null) {
//If directory then create a new directory in uncompressed folder
if (entry.isDirectory()) {
loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
"Creating Directory:" + pathToFile));
Files.createDirectories(pathToFile);
} else {
Files.createFile(pathToFile);
loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
"File unzip: " + pathToFile.getFileName()));
try (FileOutputStream fileOutputStream = new FileOutputStream(pathToFile.toString())) {
int len;
while ((len = zipInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, len);
}
}
entry = zipInputStream.getNextEntry();
}
}
return true;
} catch (final IOException e) {
loggerAnalysis.log(new LogRecord(Level.ERROR, "[Analysis]", e.getMessage()));
return false;
}
}
best regards

How to download large zip file (1 -2 GB) using SpringBoot Rest API Apache CXF implementation?

How to download large zip file (1 -2 GB) using SpringBoot Rest API Apache CXF implementation ?
i have tried using Output Stream but no luck.
InputStream inputStream = new FileInputStream(new File(file));
return new StreamingResponseBody() {
#Override
public void writeTo(OutputStream outputStream)
throws IOException {
int nRead;
byte[] data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
System.out.println("Writing some bytes..");
outputStream.write(data, 0, nRead);
}
inputStream.close();
}
};
I tried below code and it is able to download 500MB file, but it should work for 1-2 GB file as well :
try {
String link = "https://s.basketbuild.com/uploads/devs/dianlujitao/oneplus3/cm13/cm-13.0-20160621-UNOFFICIAL-oneplus3.zip";
URL url = new URL(link);
System.out.println("Started reading the zip");
File dir = new File("C:\\Softwares\\testdownload");
if (!dir.exists())
dir.mkdirs();
String fileBaseName = "TestDownload";
String fileExtension = "zip";
System.out.println("Name: " + fileBaseName + '.' + fileExtension);
File outputFile = new File(dir, fileBaseName + '.' + fileExtension);
if (!outputFile.exists()) {
outputFile.createNewFile();
}
InputStream inputStream = new BufferedInputStream(url.openStream());
OutputStream byteArrayOutputStream = new BufferedOutputStream(new FileOutputStream(outputFile));
int n = 0;
byte[] buf = new byte[1024];
long duration = System.currentTimeMillis();
while ((n = inputStream.read(buf)) != -1) {
byteArrayOutputStream.write(buf, 0, n);
}
duration = System.currentTimeMillis() - duration;
System.out.println("Finish in " + duration + "ms");
inputStream.close();
// release outputstream
byteArrayOutputStream.close();
System.out.println("Your download has been finished");
} catch (MalformedURLException e) {
e.printStackTrace();
System.out.println("Something unexpected has happened!");
} catch (IOException e) {
e.printStackTrace();
System.out.println("Something unexpected has happened!");
}

how to upload an image using servlet to an absolute path

I want to upload a file to my project folder. My code is as follows:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File savedFile;
String destination;
List<FileItem> items = null;
try {
items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (FileItem item : items) {
if (item.isFormField()) {
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
} else {
// Process form file field (input type="file").
String fieldName = item.getFieldName();
String fileName = FilenameUtils.getName(item.getName());
InputStream fileContent = item.getInputStream();
String userName = (String) session.getAttribute("newUser");
destination = getServletConfig().getServletContext().getContextPath() + "\\" + userName + ".jpeg";
savedFile = new File(destination);
//Check if file exists
if(!savedFile.exists())
savedFile.createNewFile();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(savedFile));
byte[] buffer = new byte[1024];
int len;
//Read from file and write to new file destination
while((len = fileContent.read(buffer)) >= 0) {
bos.write(buffer, 0, len);
}
//Closing the streams
fileContent.close();
bos.close();
}
}
}
When I run the jsp file and browse and select the required image and submit the form, the servlet runs but it throws IOException. The exception is throws by the line where I create a new path using savedFile.createNewFile(). Before I used that code, it threw another FileNotFoundException. I am not sure if the path that I have provided is correct.
Try to use getRealPath() method.
String fileName="/" + userName + ".jpeg";
destination = getServletContext().getRealPath(fileName);
savedFile = new File(destination);

How do I read and write UTF-8 encoding from java assets folder? I have the code, but its not working. I get �D�nde est� / D�nde

private void CopyAssets2() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("File Error", e.getMessage());
}
for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
out = new FileOutputStream("/sdcard/Translate/" + filename);
copyFile2(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("Save Error", e.getMessage());
}
}
}
private void copyFile2(InputStream in, OutputStream out)
throws IOException {
char[] buffer = new char[1024];
Reader reader = new BufferedReader( new InputStreamReader(in, "UTF-8"));
Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
int read;
while ((read = reader.read(buffer)) != -1) {
writer.write(buffer, 0, read);
}
reader.close();
writer.flush();
writer.close();
}
Im getting the inputstream with assetManager, and passing it as a parameter of reader with UTF-8 encoding specified.
I'm also doing writing to the outputstream filepath with writer in UTF-8
The file is read and written, but the encoding is still wrong. I get characters like these:
Where are... = �D�nde est� / D�nde
What I am doing wrong?
Are you sure the input file is encoded in UTF-8? The � you see in the output is a character that is used as a replacement for byte sequences that could not be converted into characters when reading.
You could make a binary copy instead of decoding and encoding text:
byte[] buffer = new byte[1024];
InputStream reader = new BufferedInputStream(in);
OutputStream writer = new BufferedOutputStream(out);
int read;
while ((read = reader.read(buffer)) != -1) {
writer.write(buffer, 0, read);
}

Resources