9

I want to know, how to write a file to a resources folder in a Spring MVC project. I defined the resources path in a web-dispatcher-servlet.xml as
<mvc:resources mapping="/resources/**" location="/resources/" />

I read examples about how to read a file from a resources folder. But I want to write a file to a resources folder. I tried

ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("file/test.xml").getFile());
    if (file.createNewFile()) {
        System.out.println("File is created!");
    } else {
        System.out.println("File already exists.");
    }

But I get a
Request processing failed; nested exception is java.lang.NullPointerException

Abecee
  • 2,365
  • 2
  • 12
  • 20

3 Answers3

9

If you want to create a test.xml file in the directory returned by getResource(), try this:

File file = new File(classLoader.getResource(".").getFile() + "/test.xml");
if (file.createNewFile()) {
    System.out.println("File is created!");
} else {
    System.out.println("File already exists.");
}

Calling getFile() on a non-existent directory or file will return null, as explained in Reid's answer.

Shawn Bush
  • 644
  • 3
  • 6
3

It looks like your call to getResource("file/test.xml") is likely returning null.

I'm curious, what is the full path to your XML file? For this to work, the resources directory needs to be placed in your webapp directory. If you are trying to use the standard Java resources structure (src/main/resources) then that Spring MVC mapping will not work.

EDIT: After seeing your answer to @Ascalonian's comment, this will not work since the file doesn't exist. Like I mentioned earlier, getResource("file/test.xml") will return null so the following call to getFile() will throw the NPE. Maybe you should check if getResource returns null and use that as an indication that the file needs to be created.

Reid Harrison
  • 406
  • 3
  • 9
1

Firstly, you should not write to a file in resource folder, as it will get deleted whenever you do a fresh build. Instead store it in some other location and specify the path in a property file.

You can use the following way to create a file :

String rootPath = System.getProperty("user.dir");
File file = new File(StringUtils.join(rootPath, "/any/path/from/your/project/root/directory/" , "test.xml"));
//Below commented line is what you wish to do. But I recommend not to do so.
//File file = new File(StringUtils.join(rootPath, "/out/resources/file/" , "test.xml"));
file.createNewFile();
Sahil Chhabra
  • 10,621
  • 4
  • 63
  • 62
  • I'm not sure about that, the Resources folder can also be included within a build, how do you think tests pass in a deployed environment? – Arsalan Khalid Sep 16 '18 at 15:13
  • @Arsalan As per my understanding, resource folder content/files can be included in build at the root path of your jar. But, I guess you can't read or edit it. In a deployed environment, you need to copy that resource content to a location your jar file can access by writing your code and build/deploy script accordingly. – Sahil Chhabra Oct 07 '18 at 05:59