How to load folder using classpath in java [duplicate] - java

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

Related

Find files in inner zipfile Commons VFS

Is it possible to use the FileObject::findFiles method or similar to search in ZIP files which are stored in a folder? Or do I have to open the zipfiles by myself?
FileObject root = vfs.resolveFile(file:///home/me/test/vfsdir);
// shows everything except the content of the zip
FileObject[] allFiles = root.findFiles(Selectors.SELECT_ALL);
// should contain only the three xmls
FileObject[] xmlFiles = root.findFiles(xmlSelector);
VFS Directory-Tree
/ (root)
/folderwithzips
/folderwithzips/myzip.zip (Zipfile not a folder)
/folderwithzips/myzip.zip/myfile.xml
/folderwithzips/myzip.zip/myfile2.xml
/folderwithzips/other.zip
/folderwithzips/other.zip/another.xml
Sadly it's not possible to search through the content of zips in a VFS as if they were folders.
So I have to load every zip manually and execute my selector on the content.
This small method does the trick for me.
public static void main(String[] vargs) throws FileSystemException {
FileSystemManager manager = VFS.getManager();
FileObject root = manager.resolveFile("/home/me/test/vfsdir");
List<FileObject> files = findFiles(root, new XMLSelector());
files.stream().forEach(System.out::println);
}
public static List<FileObject> findFiles(FileObject root,FileSelector fileSelector) throws FileSystemException {
List<FileObject> filesInDir = Arrays.asList(root.findFiles(fileSelector));
FileObject[] zipFiles = root.findFiles(new ZipSelector());
FileSystemManager manager = VFS.getManager();
List<FileObject> filesInZips = new ArrayList<>();
for (FileObject zip: zipFiles){
FileObject zipRoot = manager.createFileSystem(zip);
Stream.of(zipRoot.findFiles(fileSelector)).forEach(filesInZips::add);
}
return Stream.concat(filesInDir.stream(),filesInZips.stream()).collect(Collectors.toList());
}

How to get the root path of my project?

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.

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

Read a file residing inside a jar being called from another jar file

I have two jar files (Lets say jar1 and jar2). There is one xml file inside a jar2. I want to read the xml file. i used
public void readXmlFile(){
InputStream resourceAsStream = MainFile.class.getResourceAsStream("/test.xml");
}
But now i am calling this function frm a class in jar1 using
File file = new File(jar2);
URL url = file.toURL();
URL[] urls = new URL[] { url };
ClassLoader cl = new URLClassLoader(urls);
Class<?> compositeClass = cl.loadClass(XmlFileReader);
Method declaredMethod = compositeClass.getDeclaredMethod("readXmlFile");
Object newInstance = compositeClass.newInstance();
declaredMethod.invoke(newInstance);
Now I am getting FileNotFoundException as the xml file is being searched in jar1 and not in jar2, I do not know why is this happening. Can anyone help me?
Th Only solution i found is to set a System property using System.setProperty(key, value) in my jar1 as the path of the folder containing my both the jars. Then i read the system property back in my jar2 and then modified my readXml method like this
public void readXmlFile(){
JarFile jarFile = new JarFile(pathToJar2);
JarEntry entry = jarFile.getJarEntry("/test.xml");
InputStream inputStream = jarFile.getInputStream(entry);}

Uploading files to a webserver java FileUpload

I'm using apache's FileUpload in order to upload some files to my webserver. Problem is I don't want to upload them to a specific location on the machine i.e : c:\tmp, but rather to a relative path such as /ProjectName/tmp/
Here's my code:
private static final long serialVersionUID = 1L;
private String TMP_DIR_PATH = "c:\\tmp";
private File tmpDir;
private static final String DESTINATION_DIR_PATH ="/files";
private File destinationDir;
public void init(ServletConfig config) throws ServletException {
super.init(config);
tmpDir = new File(TMP_DIR_PATH);
if(!tmpDir.isDirectory()) {
throw new ServletException(TMP_DIR_PATH + " is not a directory");
}
String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
destinationDir = new File(realPath);
if(!destinationDir.isDirectory()) {
throw new ServletException(DESTINATION_DIR_PATH+" is not a directory");
}
}
I want to change TMP_DIR_PATH so it's relative to my project, help would be appreciated!
If your actual concern is the hardcoding of the c:\\tmp part which makes the code unportable, then consider using File#createTempFile() instead. This will create the file in the platform default temp location as specified by the java.io.tmpdir system property.
File file = File.createTempFile("upload", ".tmp");
OutputStream output = new FileOutputStream(file);
// ...
If you want the temp directory to be relative to your project you'll have to use getRealPath and then make sure you create the directory if it doesn't already exist.
You can also use File dir = (File) getServletContext().getAttribute("javax.servlet.context.tempdir"); to fetch an app-specific temp directory provided by the container.

Categories

Resources