I'm new to Spring MVC. I created a new spring controller method that takes an fileoutputstream and writes xml to it as follows:
#RequestMapping(value = "/xml", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
public final void getMappingsAsXML(HttpServletResponse response) {
Customer customer = getCustomerMappings();
try {
// Generates xml file
xmlHelper.save(customer, new StreamResult(new FileOutputStream("/WEB-INF/content/customermapping.xml")));
// print to browser
// read generated file and write to response outputsteam
} catch (XmlMappingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
However, the above code throws the below exception:
java.io.FileNotFoundException: /WEB-INF/content/customermapping.xml (No such file or directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
at java.io.FileOutputStream.<init>(FileOutputStream.java:84)
The content directory already exists in the WEB-INF folder. Also, are there any better ways to write a file to browser in spring?
[BTW, I'm using maven.]
By using a path of /WEB-INF/content/customermapping.xml you are telling Java to write a file named customermapping.xml to the WEB-INF/content directory at the root of the drive. This doesn't sound like what you want.
Try removing the leading /.
However it's probably a bad idea to write to files within the same directory hosting your web application, as some servlet containers like Tomcat simply remove the entire directory when you undeploy the application (with the default settings). Much better to write to a directory external to the webapp.
Related
I'm running a Spring REST application inside a docker container. I have a function inside a Spring controller for saving images and a function for reading them. The function for saving works properly but I have an issue with the function for reading them:
public byte[] getByteArray(String fileName) {
try {
File f = new File("/upload/" + fileName);
return Files.readAllBytes(f.toPath());
} catch (IOException e) {
e.printStackTrace(); // this is for testing
return null;
}
}
However after I use the above function I get this error java.nio.file.NoSuchFileException: /upload/test.png. I checked and this file exists in this directory. What could be the reason Java can't see this file?
Most likely your /upload directory is not accessible to the java process. directories have access rights, an owner, and a group. There is one set of rights for the owner, one for the group, and one for the rest.
I've recently inherited a Java API and am having trouble with file uploads. Unfortunately, Java isn't a language I have much experience in so I'm a bit stumped by this.
The MultiPartFile is being received ok, and I can find the file in the temp directory, but when I try to use File.transferTo() to create the final file I just get the below error;
java.nio.file.NoSuchFileException: C:\Users\myUser\AppData\Local\Temp\undertow3706399294849267898upload -> S:\Dev\PolicyData\Temp.xlsx
As I mentioned the temp undertow file exists, and the directory on the S drive also exist, (but there's no Temp.xlsx as my understanding is this should be created by transferTo()). Any solutions I've found to this problem so far are resolved using absolute file paths.
This is a simplified version of the code but the error remains the same.
SpringBoot framework is "1.5.3.RELEASE", running Java 1.8.0_131
ResponseEntity handleFileUpload(#RequestPart(name = "file") MultipartFile file, #PathVariable Long stageFileTypeId) {
if (!file.isEmpty()) {
try {
String filePath = "S:\\Dev\\PolicyData\\Temp.xlsx";
log.info("Upload Path = {}", filePath);
File dest = new File(filePath);
file.transferTo(dest);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(filePath));
}
catch (Exception ex) {
log.error("An error has occurred uploading the file", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
else {
log.error("An error has occurred, no file was received");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
If you need any more information please let me know.
Thanks,
Neil
The API for MultipartFile is a bit tricky. The transferTo(File) method javadoc states that (bold are mine):
This may either move the file in the filesystem, copy the file in the
filesystem, or save memory-held contents to the destination file. If
the destination file already exists, it will be deleted first.
If the target file has been moved in the filesystem, this operation
cannot be invoked again afterwards. Therefore, call this method just
once in order to work with any storage mechanism.
It seems that the Undertow implementantion already called it to move the in-memory uploaded file to "C:\Users\myUser\AppData\Loca\Temp\undertow3706399294849267898upload" so another transferTo is failing.
I came across the same problem using javax.servlet.http.Part in a Wildfly containter with Undertow.
If you are using Spring framework >= 5.1, you could try the Multipart.transferTo(Path) method, using dest.toPath()
Or you can copy from the inputStream, with something like this:
try (InputStream is = multipartFile.getInputStream()) {
Files.copy(is, dest.toPath());
}
I want to create a file in my WebContent folder in my dynamic webproject ,I am calling a class from cron job scheduler and trying to create a file in webcontent folder the creation of file code is in a execute method of that cron job,I tried in many ways but i cant create a file it is saying
The system cannot find the path that specified
Here's my code
File file = new File("files/MatUserInformationService2207q.txt");
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block`enter code hereenter code here
e.printStackTrace();
}
On local machine (localhost), in a java class file of a web application, I am giving file path as under.
JRBeanCollectionDataSource bean = new JRBeanCollectionDataSource(al);
try {
print = JasperFillManager.fillReport("D://vivek's//powerSpace//report//bus.jasper",
new HashMap(), bean);
} catch (JRException e) {
e.printStackTrace();
}
return al;
}
But when this web application is hosted on server, how to give the absolute path of the file.
Use the resources for this.
EG:
put the bus.jasper into resources folder of your webapp, then use:
InputStream resource = getClass().getClassLoader().getResourceAsStream("bus.jasper");
and work with the InputStream from there.
If the API of the class you're using is so lame that it needs the filepath use
ConstantDataManager.class.getClassLoader().getResource("bus.jasper").getPath();
The second solution doesn't work well on Weblogic though.
I have parsed a batch of XML Schema files using a DOMparser. I than added several annotations, which are essential for the application I am creating. I then want to write these new "preprocessed" files to a new location, and I get a FileNotFound exception (access denied).
Here's the snippet of code where I am writing the file:
Transformer tFormer = TransformerFactory.newInstance().newTransformer();
// Set output file to xml
tFormer.setOutputProperty(OutputKeys.METHOD, "xml");
// Write the document back to the file
Source source = new DOMSource(document);
File preprFile = new File(newPath(xmlFile));
// The newPath function is a series of String operations that result in a new
relative path
try {
// Create file if it doesn't already exist;
preprFile.mkdirs();
preprFile.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
Result result = new StreamResult(preprFile);
tFormer.transform(source, result);
And the error I am getting is the following:
java.io.FileNotFoundException: absolutePathHere (Access is denied)
Which points to this line in the above snippet :
tFormer.transform(source, result);
I'm using a Windows machine (read somewhere that that can be the source of this error), and I've already tried turning UAC off, but no success.
I was thinking maybe the createNewFile() method doesn't release the file after it's been made, but was unable to find more information about that.
Here's hoping StackOverflow can come to my rescue once again.
It's probably running under a user account that doesn't have the rights to that directory.
You said "The directory is created, and it appears the file is created as a directory as well". So I think it creates directory named 'wsreportkbo_messages.xsd'
It gives you error may be because you are trying to read directory. You can list files in directories using listFiles().
You cannot open and read a directory, use the isFile() and isDirectory() methods to distinguish between files and folders.
I found the solution:
File preprFile = new File(directory1/directory2/directory3/file.xsd);
File directory = new File(directory1/directory2/directory3/);
try {
// Create file if it doesn't already exist;
directory.mkdirs();
preprFile.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
Thanks for the help.