How to get the root path of my project? - java

I have JSP projects that run in Tomcat developed in Eclipse.
I want to have some files which I store inside the project.
Here is the project structure that I have:
.settings
build
data
ImportedClasses
src
WebContent
.classpath
.project
I want to access the data folder from my code in JSP file which located in WebContent.
Tried some code below:
File userDataDirFile = new File ( "data" );
String path = userDataDirFile.getAbsolutePath();
prints
C:\Program Files\eclipse\data\users
Then
this.getClass().getClassLoader().getResource("").getPath()
prints
C:/Workspaces/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/survey/WEB-INF/classes/
Another one:
System.getProperty("user.dir")
prints
C:\Program Files\eclipse
There is no code that I tried (I think the 2nd solution supposed to work, but it doesn't) can locate me to root folder of my project. Anyone can advise?

String caminhoProjeto = Thread.currentThread().getContextClassLoader().getResource("").getPath();
This is like "src" path, but is the "classes" path of binaries files context after deployment and runtime.
My class for example of the necessarie use of this way "root dir of project":
PropertiesReader.java:
public class PropertiesReader {
public static String projectPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
public static String propertiesPath = "/META-INF/";
public static Properties loadProperties(String propertiesFileName) throws IOException {
Properties p = new Properties();
p.load(new FileInputStream(projectPath + propertiesPath + propertiesFileName));
return p;
}
public static String getText(String propertiesFileName, String propertie) {
try {
return loadProperties(propertiesFileName).getProperty(propertie);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return propertie;
}
}
PersonRegistration.java:
#ManagedBean
public class PersonRegistration {
private Integer majority = Integer.parseInt(PropertiesLeitor.getText("Brasil.properties", "pessoa.maioridade"));
}
Brasil.properties (within src / META-INF):
pessoa.maioridade = 18

Edit : File that are not in WebContent will not be deployed with your war. you have to put files used in you code inside the WebContent and try with ServletContext which point to the root folder of the your web application :
if your file is at the same folder as WEB-INF then :
ServletContext context = getContext();
String fullPath = context.getRealPath("/data");
by the way if you don't want to give direct access to data file it's recommanded to put it in WEB-INF so that no one can have access to them directly.

Related

Reading from config.file throws FileNotFoundException (no such file or directory)

this is my project structure
- src
-- java
--- utils
---- ConfigFileReader
--- resources
---- config.properties
this is ConfigFileReader class:
public class ConfigFileReader {
public static String getProperty(String key) {
Properties properties = new Properties();
try {
InputStream inputStream = new FileInputStream("/config.properties");
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
return properties.getProperty(key);
}
}
and this is my config.properties file:
account_storage_technology=cognito
Unfortunately executing that method throws
java.io.FileNotFoundException: /config.properties (No such file or directory)
How can I fix?
You need to keep the resources folder in the same level as src. Like this:
- src
- java
- utils
- ConfigFileReader
- resources
- config.properties
And modify the path as below :
InputStream inputStream = new FileInputStream("resources/config.properties");
UPDATE : It is not advisable or a good idea to keep properties files inside packages and read it from there. However you can make your code read the file by showing the absolute full path.
Example :
InputStream inputStream = new FileInputStream("C:\\Project-Path\\Project-Name\\src\\java\\resources\\config.properties");
// Project-Path : This is the path where your Project Parent folder resides.
// Project-Name : This is the name of your project.
when you do '/' in the begining it will try to read from your root directory. Remove the / and as long as the config.properties is present in src/main/resources, the FileInputStream should be able to pick the config file.
ConfigFileReader.class.getResourceAsStream("config.properties")

How to load folder using classpath in java [duplicate]

I have the following directory layout:
src
main
java
resources
sql (scripts for database)
spring (configuration)
webapp
Within a ServletContextListener class, I want to access the files under the SQL directory and list them. Basically my problem is with the path, because I know that listing files under a directory in a nutshell is:
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
Maybe I could use the ServletContextEvent Object to try and build a path to resources/sql
public void contextInitialized(ServletContextEvent event) {
event.getServletContext(); //(getRealPath etc.)
}
Does something exist to set that path in a relative, non-hardcoded way?
Something like new File("classpath:sql") (preferably spring if possible) or what should I do with the servletContext to point at resources/sql?
I'm assuming the contents of src/main/resources/ is copied to WEB-INF/classes/ inside your .war at build time. If that is the case you can just do (substituting real values for the classname and the path being loaded).
URL sqlScriptUrl = MyServletContextListener.class
.getClassLoader().getResource("sql/script.sql");
Finally, this is what I did:
private File getFileFromURL() {
URL url = this.getClass().getClassLoader().getResource("/sql");
File file = null;
try {
file = new File(url.toURI());
} catch (URISyntaxException e) {
file = new File(url.getPath());
} finally {
return file;
}
}
...
File folder = getFileFromURL();
File[] listOfFiles = folder.listFiles();
import org.springframework.core.io.ClassPathResource;
...
File folder = new ClassPathResource("sql").getFile();
File[] listOfFiles = folder.listFiles();
It is worth noting that this will limit your deployment options, ClassPathResource.getFile() only works if the container has exploded (unzipped) your war file.
Just use com.google.common.io.Resources class. Example:
URL url = Resources.getResource("file name")
After that you have methods like: .getContent(), .getFile(), .getPath() etc

Upload file to Spring Boot Resource Folder, should not be that hard right

I checked all over the internet and still cannot find the correct answer. I want to upload a file to the resources folder from Spring. So I can get the file from the heroku server when I deploy it.
For example applicationname/herokuapp.com/image.jpg
The structure of my app:
I tried and got a few problems :
File not found exception
Illegal char <:> at index 2
The file path I get is in the target folder??
Can't find path
I just need to get the correct path to the resources folder but I can't get it.
My controller with the following method looks like this:
#PostMapping(value = "/sheetmusic")
public SheetMusic create(HttpServletRequest request, #RequestParam("file") MultipartFile file, #RequestParam("title") String title, #RequestParam("componist") String componist, #RequestParam("key") String key, #RequestParam("instrument") String instrument) throws IOException {
URL s = ResourceUtils.getURL("classpath:static/");
String path = s.getPath();
fileService.uploadFile(file,path);
SheetMusic sheetMusic = new SheetMusic(title,componist,key,instrument,file.getOriginalFilename());
return sheetMusicRepository.save(sheetMusic);
}
The FileService:
public void uploadFile(MultipartFile file, String uploadDir) {
try {
Path copyLocation = Paths
.get(uploadDir + File.separator + StringUtils.cleanPath(file.getOriginalFilename()));
Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
I read something about jar but I don't understand it. I did not think it was this hard to just upload a file to a folder but I hope you guys can help me out!
EDIT :
When I add this :
String filePath = ResourceUtils.getFile("classpath:static").toString();
It will upload to the target folder which is not right.
EDIT 2 : IT IS FIXED
This is the right way to get the correct path :
String path = new File(".").getCanonicalPath() + "/src/main/webapp/WEB-INF/images/";
fileService.uploadFile(file,path);
My folder structure is the following:
main
-java
- webapp
- WEB-INF
- images
Then I had to put this code into my MainApplicationClass
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Register resource handler for images
// Register resource handler for images
registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/")
.setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic());
}
What you are trying to do here (replacing a file/uploading a file INTO a package .jar file) does not work, it is literally impossible.
You need to upload your file somewhere else, be that S3, some network drive etc, so that you application can reference it.

Why I cant read properties file using getResourceAsStream when it is in classpath (under WEB-INF/lib)

I was testing out reading a properties file using getResourceAsStream when the properties file is in classpath (under WEB-INF\lib folder). And it is not working for some reason. Can anybody tell me what I am doing wrong?
This is my environment: Operating system is Windows 7. IDE is Eclipse 4.2.3 Kepler 64-bit. Server is Tomcat 6.0.37 running on 8081 port.
I created a web application MyWebProject.
I have a app.properties file which is located in WEB-INF\lib folder. This is the content of app.properties file:
DataSource=jdbc/MyDB
I created a class AppProperties which reads this file. This is the class:
public final class AppProperties {
private static String DATA_SOURCE_NAME;
public static String getDataSourceName() {
return DATA_SOURCE_NAME;
}
static {
ClassLoader classLoader = null;
InputStream propertiesFile = null;
Properties properties = null;
final String PROPERTIES_FILE_NAME = "app.properties";
properties = new Properties();
classLoader = Thread.currentThread().getContextClassLoader();
System.out.println("AppProperties: Name of classLoader = " + classLoader.getClass().getName());
propertiesFile = classLoader.getResourceAsStream(PROPERTIES_FILE_NAME);
System.out.println("AppProperties: propertiesFile = " + propertiesFile);
}
}
Then I created a Servlet AppPropertiesServlet to test it out:
public class AppPropertiesServlet extends HttpServlet {
public AppPropertiesServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String dataSourceName = null;
dataSourceName = AppProperties.getDataSourceName();
}
}
I deployed the web application MyWebProject on Tomcat. So under webapps folder of Tomcat, a new folder MyWebProject was created with all the necessary files. I then run the servlet http://localhost:8081/MyWebProject/AppPropertiesServlet
and this is what appears on Tomcat console:
AppProperties: Name of classLoader =
org.apache.catalina.loader.WebappClassLoader AppProperties:
propertiesFile = null
Why the propertiesFile is null? The app.properties file is in the WEB-INF\lib folder of MyWebProject folder but somehow the classloader is unable to find it. Strange. What I am doing wrong here?
Thanks
If you want it to be under WEB-INF/lib it has to be packaged inside the JAR.
If you want it to be like a normal file , it has to be inside WEB-INF/classes.

How to get resources directory path programmatically

I have the following directory layout:
src
main
java
resources
sql (scripts for database)
spring (configuration)
webapp
Within a ServletContextListener class, I want to access the files under the SQL directory and list them. Basically my problem is with the path, because I know that listing files under a directory in a nutshell is:
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
Maybe I could use the ServletContextEvent Object to try and build a path to resources/sql
public void contextInitialized(ServletContextEvent event) {
event.getServletContext(); //(getRealPath etc.)
}
Does something exist to set that path in a relative, non-hardcoded way?
Something like new File("classpath:sql") (preferably spring if possible) or what should I do with the servletContext to point at resources/sql?
I'm assuming the contents of src/main/resources/ is copied to WEB-INF/classes/ inside your .war at build time. If that is the case you can just do (substituting real values for the classname and the path being loaded).
URL sqlScriptUrl = MyServletContextListener.class
.getClassLoader().getResource("sql/script.sql");
Finally, this is what I did:
private File getFileFromURL() {
URL url = this.getClass().getClassLoader().getResource("/sql");
File file = null;
try {
file = new File(url.toURI());
} catch (URISyntaxException e) {
file = new File(url.getPath());
} finally {
return file;
}
}
...
File folder = getFileFromURL();
File[] listOfFiles = folder.listFiles();
import org.springframework.core.io.ClassPathResource;
...
File folder = new ClassPathResource("sql").getFile();
File[] listOfFiles = folder.listFiles();
It is worth noting that this will limit your deployment options, ClassPathResource.getFile() only works if the container has exploded (unzipped) your war file.
Just use com.google.common.io.Resources class. Example:
URL url = Resources.getResource("file name")
After that you have methods like: .getContent(), .getFile(), .getPath() etc

Categories

Resources