Not able to save the image to disk in linux using springboot - java

I am trying to save images to disk using spring boot and angular, however there are no
exceptions thrown in the below code nor any errors, but i cannot see image in the required folder
#RestController
#CrossOrigin(origins = "http://localhost:4200")
public class ImageController {
#RequestMapping(value = "/postImages", method = RequestMethod.POST, consumes =
MediaType.MULTIPART_FORM_DATA_VALUE )
public ResponseEntity<Void> uploadPolicyDocument(#RequestParam("image")
List<MultipartFile> multipartFile)
{
String OUT_PATH = "home\\krishnachaitanya\\Pictures\\testing\\";
try {
for(MultipartFile mf: multipartFile)
{
byte[] bytes = mf.getBytes();
Path path = Paths.get(OUT_PATH+ mf.getOriginalFilename());
Files.write(path, bytes);
}
} catch (IOException e) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return ResponseEntity.ok().build();
}

Actually I think the file is successfully written, but not in the place you would expect. '\' is not a path separator on Linux and the path you specify is relative, so the file is written in the applications working directory. The file is named: home\krishnachaitanya\Pictures\testing\oryginalFileName.
Change the OUT_PATH to "/home/krishnachaitanya/Pictures/testing/"

The OUT_PATH looks very wrong for a linux system. have you tried to use "/" instead of "\\"

Related

Spring boot multi part files upload storing data wondering

I have this service in spring boot app:
#Service
public class FileStorageService {
private final Path root = Paths.get("uploads");
public void init() {
try {
Files.createDirectories(root);
} catch (IOException e) {
throw new RuntimeException("Could not initialize folder for upload!");
}
}
public ResponseEntity<?> save(MultipartFile[] files) {
if (files.length == 0) {
//return ResponseEntity.badRequest();
}
Arrays.asList(files).stream().forEach(file -> {
try {
// Get the file and save it somewhere
byte[] bytes = file.getBytes();
Path path = Paths.get(root + File.separator + file.getOriginalFilename());
Files.write(path, bytes);
} catch (IOException e) {
e.printStackTrace();
}
});
return new ResponseEntity<>(null, HttpStatus.OK);
}
}
There is some folder for saving files "uploads". And i am now wondering what is
spring.servlet.multipart.location=
setting used for. Is this just folder where raw data from request are stored before they are saved in "uploads" folder?
As mentioned in this document for spring.servlet.multipart.location,
location specifies the directory where uploaded files will be stored.
When not specified, a temporary directory will be used.
I dig around some internal code and found out that, it depends on the spring.servlet.multipart.file-size-threshold configuration. As mentioned in the doc
specifies the size threshold after which files will be written to disk. The default is 0.
If you mention any non-zero value then it will attempt to store that much in memory first before, writing to disk.
For your case, if you mention any location in spring.servlet.multipart.location the file will directly stored over that location only.
You may also want to check spring.servlet.multipart.max-file-size and spring.servlet.multipart.max-request-size property.

can not find files in jar build b Spring Boot

these logs and the Controller Class are self-explanatory:
logs:
java.io.FileNotFoundException: class path resource [/static/index.html] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/home/mehrdad/ocr/main/ocr-web/target/ocr-web-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/static/index.html
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:217)
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:180)
at com.pouya.ocr.web.web.RouteController.defaultPath(RouteController.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Class:
#Controller
public class RouteController {
#RequestMapping(value = "/app/**", method = RequestMethod.GET)
public ResponseEntity<String> defaultPath() {
System.out.println("Unmapped request handling!");
try {
File index = ResourceUtils.getFile("classpath:/static/index.html");
FileInputStream inputStream = new FileInputStream(index);
String body = StreamUtils.copyToString(inputStream, Charset.defaultCharset());
return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(body);
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error in redirecting to index");
}
}
}
the second ! seems to cause the problem:
../ocr-web-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/static/index.html
How to solve this?
I tried to use classpath:static/index.html instead of classpath:/static/index.html, nothing changed.
I solved the problem.
do not use ResourceUtils(sometimes Spring does not make Java simpler!)use old java way for loading resource from classPath:
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("/static/index.html");

Spring Boot rest controller not working when package in a jar

I am developing a REST API using Spring Boot rest controller. Something strange is happening ; When I test my controller with Eclipse it is working just fine BUT when i deploy the app, packaged in a jar and started with the "java" command line in a docker container then, it doesn't work.
What confuse me is that there is no log. And when I put a sysout at the very beginning of my controller I realized that the controller is not even executed !
Here is the controller with the concerned endpoint, but i am not sure it will help :
#RestController
#RequestMapping("/pdf")
#EnableSwagger2
public class PDFGeneratorResources {
#Autowired
PDFGenerator pdfService;
#Autowired
ResourceLoader resourceLoader;
#PostMapping("/generate-recipies-shoppinglist")
public ResponseEntity<String> generateRecipiesAndShoppingListPDF(#RequestBody List<Day> daysList) {
System.out.println("TRACE");
ResponseEntity<String> responseEntity = null;
String generatedPDFFileURL = "";
try {
generatedPDFFileURL = pdfService.generatePDFFromHTML(PDFTemplates.RecipiesAndShoppingList,
new RecipiesShoppinglistContextBuilder(new ArrayList<Day>(daysList)));
responseEntity = new ResponseEntity<String>(generatedPDFFileURL, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
responseEntity = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return responseEntity;
}
}
Question : Is there any way of making spring boot log everything that's happening between tomcat and my controller ? King of --verbose option for spring boot ?
PS:
Here is the DockerFile I am using to deploy the app
FROM registry.gitlab.com/softreaver/meals-ready-backend/runners:centos7jdk11
MAINTAINER MILAZZO_christopher
COPY ./target/*.jar /app.jar
RUN echo -e "/usr/bin/java -Xms128m -Xmx128m -jar /app.jar\n" > /start-app.sh
RUN chmod u+x /start-app.sh
EXPOSE 8080
ENTRYPOINT ["/bin/bash", "/start-app.sh"]
I finally found the problem thx to log.level.root=debug ; I am using the Spring resourceloader to load the template for my PDF service but it seems that it is not able to find the resources folder inside a jar file.
It says : cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/templates/......
I found a solution on internet and made it work by using inputStream :
#Service
public class ResourceLoaderService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#Autowired
ResourceLoader resourceLoader;
public String getResourceAbsolutePathString(String location) throws Exception {
Resource resource = resourceLoader.getResource(location);
String absolutePathString = "/";
try {
if (resource.getURL().getProtocol().equals("jar")) {
logger.debug("Jar file system activated");
File tempFile = Files.createTempFile("Mealsready_backend_", null).toFile();
resource.getInputStream().transferTo(new FileOutputStream(tempFile));
absolutePathString = tempFile.getAbsolutePath();
} else {
absolutePathString = resource.getFile().getAbsolutePath();
}
} catch (IOException e) {
logger.error("Error while trying to retrieve a resource : " + e.getMessage());
// TO DELETE Remplacer par un ServiceException
throw new Exception();
}
return absolutePathString;
}
}

Spring boot - Grabbing a file from the file system in a Get Request

I am trying to grab a file (in this case an image) from the file system and display it. I can do it from a resources subdirectory just fine, but when I try to go to the file system it is giving me a FileNotFound exception.
java.io.FileNotFoundException: file:\Y:\Kevin\downloads\pic_mountain.jpg (The filename, directory name, or volume label syntax is incorrect)
All the rest of my code is vanilla spring boot that was generated from the Initialize. Thanks.
#RestController
public class ImageProducerController {
#GetMapping("/get-text")
public #ResponseBody String getText() {
return "Hello World";
}
#GetMapping(value = "/get-jpg", produces = MediaType.IMAGE_JPEG_VALUE)
public void getImage(HttpServletResponse response) throws IOException {
FileSystemResource imgFile = new FileSystemResource("file:///Y:/Kevin/downloads/pic_mountain.jpg");
// ClassPathResource imgFile = new ClassPathResource("images/pic_mountain.jpg");
System.out.println(imgFile.getURL());
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
StreamUtils.copy(imgFile.getInputStream(), response.getOutputStream());
}
}
from the docs:
public FileSystemResource(String path)
Create a new FileSystemResource from a file path
the constructor expects a path-part of the url, so in your case only Y:/Kevin/downloads/pic_mountain.jpg
so you should try to use it this way:
FileSystemResource imgFile = new FileSystemResource("Y:/Kevin/downloads/pic_mountain.jpg");
Btw. could it be, that you miss "Users" in your path? -> Y:/Users/Kevin/downloads/pic_mountain.jpg

open a file in a tomcat webapplication

i want to open a file and return its content. Although it is in the same directory like the class that wants to open the file, the file can't be found. Would be cool if you could help me solving the problem.
Here is the code:
#GET #Produces("text/html") #Path("/{partNO}/") #Consumes("text/html")
public String getPartNoResponseHTML(#PathParam("partNO") String parID) throws WebApplicationException {
PartNoTemplate partNo = getPartNoResponse(parID);
String result = "";
try {
result = readFile(PART_NO_TEMPLATE_FILE);
} catch (FileNotFoundException e) {
e.printStackTrace(System.out);
return e.getMessage() + e.toString();
// throw new WebApplicationException(Response.Status.NOT_FOUND);
} finally {
result = result.replace("{partNO}", parID);
result = result.replace("{inputFormat}", partNo.getFormat().toString());
}
return result;
}
I guess it can't find the file, because its running on tomcat. I'm also using Jersey and JAX-RS. Thank you for your help,
Maxi
If the file is inside the application WAR (or in a jar) you can try by using
InputStream input = servletContext.getClass().getClassLoader().getResourceAsStream("my_filename.txt");
Your problem is similar (I think) with How can I read file from classes directory in my WAR?
Try to get the path of the file from ServletContext.
ServletContext context = //Get the servlet context
In JAX-RS to get servlet context use this:
#javax.ws.rs.core.Context
ServletContext context;
Then get the file from your web application:
File file = new File(context.getRealPath("/someFolder/myFile.txt"));
You don't post the code that actually tries to read the file, but assuming the file is in the classpath (as you mention it's in the same directory as the class) then you can do:
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
See here

Categories