Spring Boot access static resources missing scr/main/resources

JavaSpringSpring BootResourcesSpring Properties

Java Problem Overview


I am working on a Spring Boot application. I need to parse an XML file (countries.xml) on start. The problem is that I do not understand where to put it so that I could access it. My folders structure is

ProjectDirectory/src/main/java
ProjectDirectory/src/main/resources/countries.xml

My first idea was to put it in src/main/resources, but when I try to create File (countries.xml) I get a NPE and the stacktrace shows that my file is looked in the ProjectDirectory (so src/main/resources/ is not added). I tried to create File (resources/countries.xml) and the path would look like ProjectDirectory/resources/countries.xml (so again src/main is not added).

I tried adding this with no result

@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    super.addResourceHandlers(registry);
}

I know that I can add src/main/ manually, but I want to understand why is it not working as it has to. I also tried examples with ResourceLoader - with the same no result.

Could anyone suggest what the problem is?

UPDATE: Just for future references - after building the project, I encountered problem with accessing file, so I changed File to InputStream

InputStream is = new ClassPathResource("countries.xml").getInputStream();

Java Solutions


Solution 1 - Java

Just use Spring type ClassPathResource.

File file = new ClassPathResource("countries.xml").getFile();

As long as this file is somewhere on classpath Spring will find it. This can be src/main/resources during development and testing. In production, it can be current running directory.

EDIT: This approach doesn't work if file is in fat JAR. In such case you need to use:

InputStream is = new ClassPathResource("countries.xml").getInputStream();

Solution 2 - Java

While working with Spring Boot application, it is difficult to get the classpath resources using resource.getFile() when it is deployed as JAR as I faced the same issue. This scan be resolved using Stream which will find out all the resources which are placed anywhere in classpath.

Below is the code snippet for the same -

ClassPathResource classPathResource = new ClassPathResource("fileName");
InputStream inputStream = classPathResource.getInputStream();
content = IOUtils.toString(inputStream);

Solution 3 - Java

To get the files in the classpath :

Resource resource = new ClassPathResource("countries.xml");
File file = resource.getFile();

To read the file onStartup use @PostConstruct:

@Configuration
public class ReadFileOnStartUp {
	
	@PostConstruct
	public void afterPropertiesSet() throws Exception {
		
		//Gets the XML file under src/main/resources folder
		Resource resource = new ClassPathResource("countries.xml");
		File file = resource.getFile();
		//Logic to read File.
	}
}

Here is a Small example for reading an XML File on Spring Boot App startup.

Solution 4 - Java

I use spring boot, so i can simple use:

File file = ResourceUtils.getFile("classpath:myfile.xml");

Solution 5 - Java

You need to use following construction

InputStream in = getClass().getResourceAsStream("/yourFile");

Please note that you have to add this slash before your file name.

Solution 6 - Java

You can use following code to read file in String from resource folder.

final Resource resource = new ClassPathResource("public.key");
String publicKey = null;
try {
     publicKey = new String(Files.readAllBytes(resource.getFile().toPath()), StandardCharsets.UTF_8);
} catch (IOException e) {
     e.printStackTrace();
}

Solution 7 - Java

I use Spring Boot, my solution to the problem was

"src/main/resources/myfile.extension"

Hope it helps someone.

Solution 8 - Java

> Because java.net.URL is not adequate for handling all kinds of low level resources, Spring introduced org.springframework.core.io.Resource. To access resources, we can use @Value annotation or ResourceLoader class. > @Autowired private ResourceLoader resourceLoader;

@Override public void run(String... args) throws Exception {

    Resource res = resourceLoader.getResource("classpath:thermopylae.txt");

    Map<String, Integer> words =  countWords.getWordsCount(res);

    for (String key : words.keySet()) {

        System.out.println(key + ": " + words.get(key));
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionlenach87View Question on Stackoverflow
Solution 1 - JavaluboskrnacView Answer on Stackoverflow
Solution 2 - JavaSachchidanand SinghView Answer on Stackoverflow
Solution 3 - JavaSanjay RawatView Answer on Stackoverflow
Solution 4 - JavaGalleyView Answer on Stackoverflow
Solution 5 - JavaAndrew GansView Answer on Stackoverflow
Solution 6 - JavaSanjay SharmaView Answer on Stackoverflow
Solution 7 - JavaNemanja RajkovicView Answer on Stackoverflow
Solution 8 - Javaramakotireddy nagireddyView Answer on Stackoverflow