How to set file location in application properties - Spring boot - spring-boot

I have a Spring Boot application, the code need to access a file under resources/templates folder.
here is my application.properties file:
pont.email.template.location=templates/mailTemplate.html
This is the java file where I use the variable:
#Value("${pont.email.template.location}")
private String templateLocation;
----------------
BufferedReader reader = new BufferedReader(new FileReader(templateLocation));
The problem is not get the varibale, it returns correctly, The problem is that the application do not found any file for this path.
I always get
java.io.FileNotFoundException: templates/mailTemplate.html (No such file or directory)
I have checked that the file is in the path..
what is wrong in my code?
Help please, thanks.

You cannot read a File from inside a JAR. This fails due to the fact that the File has to point to an actual file resource on the file system and not something inside a JAR.
Let Spring do the heavy lifting and use the Resource abstraction to hide the nasty internals. So instead of using a String use a Resource and prefix the value of the property with classpath: to make sure it is loaded from the classpath. Then use an InputStreamReader instead of FileReader to obtain the information you need.
#Value("${pont.email.template.location}")
private Resource templateLocation;
----------------
BufferedReader reader = new BufferedReader(new InputStreamReader(templateLocation.getInputStream()));
In your application.properties prefix with classpath:.
pont.email.template.location=classpath:templates/mailTemplate.html
Now it should work regardless of the environment you are running in.

Related

Give external path in #Value Spring annotation and Resource

In spring boot application how do I give an external windows path using #Value Spring annotation and Resource
The below example works fine that look into resources folder but I want to give the path outside of application like c:\data\sample2.csv
#Value("classPath:/sample2.csv")
private Resource inputResource;
...
#Bean
public FlatFileItemReader<Employee> reader() {
FlatFileItemReader<Employee> itemReader = new FlatFileItemReader<Employee>();
itemReader.setLineMapper(lineMapper());
itemReader.setLinesToSkip(1);
itemReader.setResource(inputResource);
and if I want to get the value from properties file in annotaion, whats the format to put the path in windows?
i tried these, none of them worked:
in code
#Value("${inputfile}")
in properties file:
inputfile="C:\Users\termine\dev\sample2.csv"
inputfile="\\C:\\Users\\termine\\dev\\sample2.csv"
inputfile="C:/Users/termine/dev/sample2.csv"
inputfile="file:\\C:\Users\termine\dev\sample2.csv"
inputfile="file://C://Users//termine///dev//sample2.csv"
When you use classpath spring will try to search with the classpath even if you provide the outside file path.
so instead of using classpath: you can use file:
Ex.
#Value("file:/sample2.csv") //provide full file path if any
Use the key spring.config.location in properties to set the config location. Spring-boot will by default load properties from the locations, with precedence like below :
A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root
and apart from this when you start the jar or in application.properties you can provide the location of the config file like :
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
You can serve static files from the local disk, by making the resource(s) "sample2.csv" as a static resource. An easy way to do this is by adding spring.resources.static-locations configuration to your applicaiton.properties file. Example:
spring.resources.static-locations=file:///C:/Temp/whatever/path/sample2.csv",classpath:/static-files, classpath:/more-static-resource
When I did this in one of the projects, I was able to access the file form the browser using localhost:8080/sample2.csv.

How do I locate resource files in a Spring Boot project deployed to Elastic Beanstalk?

My Spring Boot project contains an XML file within the src/main/resources folder, which is the common location for such a file.
Running locally and also on Pivotal CloudFoundary, I am able to locate the file and read it in, but on Beanstalk the process results in an empty file.
Code to locate and read file:
URL url = getClass().getResource("/myFile.xml");
LOG.info("File location: " + url.toString());
Resulting log entry:
File location: jar:file:/var/app/current/application.jar!/WEB-INF/classes!/myFile.xml
When I SSH into EC2 instance, I can find the jar in the specified directory.
Do I need to configure Maven to move this file somewhere?
UPDATE
I've since realized that I need to treat this file as in InputStream as it's packaged within the jar.
I'm now using the following code which results in the follow errors:
FileUtils.copyInputStreamToFile(new ClassPathResource("myFile.xml").getInputStream(), myFile);
java.lang.NullPointerException: null
at org.apache.commons.io.FileUtils.openOutputStream(FileUtils.java:345) ~[commons-io-2.5.jar:2.5]
and
FileUtils.copyInputStreamToFile(new ClassPathResource("classpath:myFile.xml").getInputStream(), myFile);
java.io.FileNotFoundException: class path resource [classpath:myFile.xml] cannot be opened because it does not exist
Thanks!
How does your pom.xml look like? Maybe there is a resource-filter active?
In a spring application you could use File file = ResourceUtils.getFile("classpath:myFile.xml"); to read a resource file.
Could you check the result by using ResourceUtils?
Here the link to the api-documentation:
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/ResourceUtils.html#getFile-java.lang.String-

Classpath resource not resolving in spring boot

I am using spring boot and I have a file in resources folder. I am using digital ocean machine and when i run the application using java -jar mywebapp.war, I am unable to access the file from classpath. I am accessing it using following standard syntax:
File file = new ClassPathResource("mfile").getFile();
I am getting error that class path resource cannot be resolved to absolute path. The problem I see is that it is showing the path with ! marks as follows:
/home/u/webapp/target/mywebapp.war!/WEB-INF/classess!/mfile
What am I doing wrong here?
Since you're running it with java -jar you should build it as a JAR file instead of WAR.
Read more: https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
Get file does not work while running as jar.you should get it as a resource Stream.
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("/file.xsd") ;
File file = File.createTempFile("file", ".xsd");
try {
FileUtils.copyInputStreamToFile(inputStream, file);
} finally {
IOUtils.closeQuietly(inputStream);
it gets you a file. if the requirement is to get as a file.

Spring Boot on Tomcat set file Paths in properties file

I want to set my relative file path in a properties file so my SaxReader can pick it up when it runs on Tomcat server. I know this should be easy but I've forgotten forgive me :)
I know Spring Boot has application.properties file but I don't see a way to hook in here.
Is there a way to set the relative path in a properties file that will get picked up by Spring Boot and the SaxReader will see it?
As it is I'm hard coding just the filename and putting the file in the resources folder that serves up the templates and static content such as css and js files. The filePath system.out gives: org.dom4j.DocumentException C:sts-bundle\sts-3.7.2.RELEASE\myFileName the toolsuite root location??? weird!!
Please tell me how to specify the relative path in a properties file.
Thanks!!
You can set the file path like any other string property in Spring Boot properties file and access it from inside the path.
E.g. I have the following set in my application.properties file:
download.directory=temp
and it is used as follows in java class:
#Value("${download.directory}")
private String downloadDirectory;
It is used to download the files, now, if I start the application with jar file present in let's say G:/applications folder then the files will be downloaded into G:/applications/temp.

Loading a file as a string content in a Spring service contained in a JAR built with Maven

I am using Spring with Maven and I would like to load a file contained in the maven folder src/main/resources inside a spring service annotated with #Service contained in a JAR file (used by another WAR file as a Maven dependency). This does not seem to work for many different reasons (read: for many different exceptions according to many different attempts).
I know that Maven, when building, puts the stuff in src/main/resources at the root of the JAR file. I've opened the JAR file and I've verified that.
I would prefer a File object (something I can use with utility libraries like Apache Commons IO), but also "something" else that's working is fine.
I would prefere going for stuff within the Java class annotated with #Service (i.e. no application context XML file, with stuff inside that I recall within the service etc.)
The file contains stuff that I eventually use as a List<String> where every item is a line in the original file. I need to keep this file as it is, I can not use a database or another solution different than a file.
This is not a .properties file and is not intended to be.
The following are the not working attempts (throwing NullPointerException, FileNotFoundException, IllegalArgumentException: URI is not hierarchical and so on...).
Among the attempts I have tried also adding/removing the prefix src/main/resources while trying to figure out what was wrong, but then I figured out that Maven puts all the stuff at the root of the JAR file as stated before.
#Value("classpath:src/main/resources/myFile.txt")
private Resource myFileResource;
private File myFile =
new File(this.getClass().getResource("/myFile.txt").toURI());
private File myFile =
new FileSystemResource("src/main/resources/myFile.txt").getFile();
private BufferedReader bufferedReaderMyFile =
new BufferedReader(
new InputStreamReader(getClass().getResourceAsStream("myFile.txt")));
What's wrong with what I am doing?
File inside jar file is no longer a File, so treat it as Resource and read it via Stream
InputStream inputStream = this.getClass().getResourceAsStream("/myFile.txt");
assumming you have actually packed that myFile.txt inside jar file and it is available at the root of JAR file

Resources