My problem is, that I want to list all the images what is located
project/src/main/webapp/images
I know if I know the image(s) name(s) I can make an URL like this:
assetSource.getContextAsset(IMAGESLOCATION + imageName, currentLocale).toClientURL();
But what if I dont know all the images name?
Thanks for the answers in advance!
The web app (and tapestry as well) doesn't know/care about absolute path of files, as it could be deployed anywhere.
You can get absolute path of some file by calling getRealPath of HttpServletRequest.
#Inject
private HttpServletRequest request;
...
// get root folder of webapp
String root = request.getRealPath("/");
// get abs path from any relative path
String abs = root + '/' + relPath;
getRealPath of HttpServletRequest is deprecated, it's recommended to use ServletContext.getRealPath instead but it's not so easy to get ServletContext.
I prefer to use WebApplicationInitializer implementation
public class AbstractWebApplicationInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
// Here we store ServletContext in some global static variable
Global.servletContext = servletContext;
....
}
You basically need the ability to read files in a given folder. Here's some very basic code that will iterate through all of the files in a folder:
File folder = new File("your/path");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
System.out.println("File " + listOfFiles[i].getName());
}
// else, it's a directory
}
All of the imports should be from the java.io package.
Related
I created folder src/test/resources/ in root project directory, and inside this I added a file in folder jsons as jsons/server_request.json.
Now I am trying to read this file by calling a the static function in CommonTestUtilityclass given as:
public class CommonTestUtility {
public static String getFileAsString(String fileName) throws IOException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
String content = new String(Files.readAllBytes(file.toPath()));
return content;
}
}
Now while calling this function as
class ServerTest {
#Test
void test_loadResource() {
String content = CommonTestUtility.getFileAsString("jsons/server_request.json");
}
}
, It's giving me the error as:
CommonTestUtility - Cannot invoke "java.net.URL.getFile()" because the return value of "java.lang.ClassLoader.getResource(String)" is null.
I tried to include the src/test/resources/ in the run configuration
of Junit ServerTest.java, but still it's not able to find out the
resource
How to resolve this issue?
https://mkyong.com/java/java-read-a-file-from-resources-folder/
This above link might be helpful.
The getResource() method return an URI you need to change
.getFile() function to. toURI().
Simple code
private File getFileFromResource(String fileName) throws URISyntaxException{
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource(fileName);
if (resource == null) {
throw new IllegalArgumentException("file not found! " + fileName);
} else {
// failed if files have whitespaces or special characters
//return new File(resource.getFile());
return new File(resource.toURI());
}
}
I recreated the same scenario you describe and your code works for me.
Could you double-check that your project looks like mine below? If so, I suspect it might be something with your environment.
I am trying to load a properties file from WEb-INF folder in my web application , which is running on Websphere 8.5 . I am using below code to load the file from the location
public class Init {
private final String WEB_INF_DIR_NAME="WEB-INF";
private String web_inf_path;
private final Properties APP_PROPERTIES =null;
InputStream inputStream = null;
public String getWebInfPath() throws IOException {
if (web_inf_path == null) {
web_inf_path = URLDecoder.decode(Init.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF8");
web_inf_path=web_inf_path.substring(0,web_inf_path.lastIndexOf(WEB_INF_DIR_NAME)+WEB_INF_DIR_NAME.length()).substring(1);
}
inputStream = Init.class.getResourceAsStream("/config/localhost/accountservice.properties");
// inputStream = this.getClass().getClassLoader().getResourceAsStream("/config/localhost/accountservice.properties");
if (inputStream != null) {
APP_PROPERTIES.load(inputStream);
}
System.out.println(APP_PROPERTIES.getProperty(AccountServiceDataAccessConstants.INET_LIBRARY_NAME)); // Here i am getting NULL
return web_inf_path;
}
}
I have also tried using servlet context , but its also giving me NULL. I have tried all possible ways to solve it but unfortunately i am not able to do it. I am also giving my folder structure.
Please excuse me if this is a silly question , but i am not really getting any idea about it.
Usually, everything in WebContent is placed in the root of your WAR file. So instead of
inputStream = Init.class.getResourceAsStream("/config/localhost/accountservice.properties");
It would be
inputStream = Init.class.getResourceAsStream("/WEB-INF/config/localhost/accountservice.properties");
The root of the WAR has WEB-INF in it, and then you can descend into your folder structure as normal.
Following ModifyXML Java class is used to read an XML file and to return all the values of specified tag's "name" attribute.
For below XML file it should return a ArrayList<String> that cantains tc_001 and tc_002.
<root>
<tc name="tc_001">
</tc>
<tc name="tc_002">
</tc>
</root>
First I created the class in a separate Java project in Eclipse with a main method which creates a new ModifyXML object and calls getTCs() method using that object. The file structure is this. In that project i used directly file path as "test.xml", which cause no error at run time.
public class ModifyXML {
/*
* constructor
* initializing main objects
*/
public ModifyXML() {
//this is the file path i used
filePath = "test.xml";
factory = DocumentBuilderFactory.newInstance();
builder = factory.newDocumentBuilder();
document = builder.parse(filePath);
}
/*
*getTCs method
*/
public ArrayList<String> getTCs(String tagType) {
ArrayList<String> tcList = new ArrayList<>();
String attributeName = "name";
NodeList nodes = document.getElementsByTagName(tagType);
int j = nodes.getLength();
for(int i = 0; i < j; i++){
Node tc = nodes.item(i);
if(tc.getNodeType() == Node.ELEMENT_NODE){
String tcName = tc.getAttributes().getNamedItem(attributeName).getNodeValue();
tcList.add(tcName);
}
}
Iterator<String> iter = tcList.iterator();
while(iter.hasNext())
System.out.println(iter.next());
return tcList;
}
public static void main(String[] args) {
ModifyXML a = new ModifyXML();
a.getTCs("tc");
}
Then i copied that class to a Dynamic Web Page project's src folder and test.xml file to the Dynamic Web Page project, then I removed main method of the class. File structure of Dynamic Web Page project is this. But when i call getTCs() method, in side servlet's service() method, an exception is occurred.
java.io.FileNotFoundException: /home/srinesh/test.xml (No such file or directory)
I'm using Ubuntu and /home/srinesh/ is my home directory. My project directory for Dynamic Web Page project is /home/dazz/Projects/workspace/Sanitizor/. Why that class looking for the test.xml file in my home directory only when the class is located in a Dynamic Web Page project?
Servlet class is showed below.
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter printWriter = response.getWriter();
ModifyXML xml = new ModifyXML("test.xml");
ArrayList<String> tc = xml.getTCs("tc");
Using relative path is not a good idea, as you see sometimes you may run the project from different directories.
So either use absolute path ("/some/path/to/your/file/file.xml") to the file, or use a classpath to read it, e.g.:
document = builder.parse(ModifyXML.class.getResourceAsStream("/" + filePath);
In the second case, you have to put the file at the root of your classpath.
In order to list file contents of a specific directory on classpath I'm using the new FileSystem and Path features of Java 7. In one deployment the directory is stored on file system, directly. In another deployment it is stored into a JAR file.
My approach works fine with JAR files: I create a FileSystem object which refers to the JAR file and access the content via Path object.
...
URI dir = ...
String[] array = dir.toString().split("!");
try (final FileSystem fs = FileSystems.newFileSystem(URI.create(array[0]), new HashMap<String, Object>()))
{
final Path directory = fs.getPath(array[1]);
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory))
{
...
Due to the dir object has following value, it works:
jar:file:/C:/Users/pax/.../Detector-1.0.jar!/org/.../destinationdir
But in the other environment the destination directory is stored on file system, directly. dir object contains the value:
file:/C:/Users/pax/.../destinationdir
FileSystems.newFileSystem(...) always throws following exception for / and file:/C:/Users/pax/.../destinationdir as URI:
java.lang.IllegalArgumentException: Path component should be '/'
at sun.nio.fs.WindowsFileSystemProvider.checkUri(WindowsFileSystemProvider.java:68)
How do you use FileSystem.newFileSystem for destinations on file system?
Is there a better approach in order to list the directories content independently from its specific kind of storage (file system or JAR file)?
Following question's resolution tackles the issue ("destination on file system" versus "destination in JAR file") by try-catch approach: NIO2: how to generically map a URI to a Path?
This utility method tries to obtain a correct Path instance. But there may occur a further problem: If this destination resource is contained by a JAR file (instead of file system) then you can only access the resource via its associated FileSystem instance which must not be closed! So, your helper method needs to return the Path object as well as the FileSystem instance (only required if it's not on file system directly). The invoker has to close the FileSystem object, manually:
public static PathReference getPath(final URI resPath) throws IOException
{
try
{
// first try getting a path via existing file systems
return new PathReference(Paths.get(resPath), null);
}
catch (final FileSystemNotFoundException e)
{
/*
* not directly on file system, so then it's somewhere else (e.g.:
* JAR)
*/
final Map<String, ?> env = Collections.emptyMap();
final FileSystem fs = FileSystems.newFileSystem(resPath, env);
return new PathReference(fs.provider().getPath(resPath), fs);
}
}
The wrapper class PathReference should implement AutoClosable so that it can be used in try block:
public class PathReference implements AutoCloseable
{
...
#Override
public void close() throws Exception
{
if (this.fileSystem != null)
this.fileSystem.close();
}
public Path getPath()
{
return this.path;
}
public FileSystem getFileSystem()
{
return this.fileSystem;
}
}
This makes the release of the FileSystem instance a bit more transparent:
...
try (final PathReference fileObj = SignatureUtils.getPath(file))
{
...
try (InputStream fileStream = Files.newInputStream(fileObj.getPath()))
{
...
i want to open a file and return its content. Although it is in the same directory like the class that wants to open the file, the file can't be found. Would be cool if you could help me solving the problem.
Here is the code:
#GET #Produces("text/html") #Path("/{partNO}/") #Consumes("text/html")
public String getPartNoResponseHTML(#PathParam("partNO") String parID) throws WebApplicationException {
PartNoTemplate partNo = getPartNoResponse(parID);
String result = "";
try {
result = readFile(PART_NO_TEMPLATE_FILE);
} catch (FileNotFoundException e) {
e.printStackTrace(System.out);
return e.getMessage() + e.toString();
// throw new WebApplicationException(Response.Status.NOT_FOUND);
} finally {
result = result.replace("{partNO}", parID);
result = result.replace("{inputFormat}", partNo.getFormat().toString());
}
return result;
}
I guess it can't find the file, because its running on tomcat. I'm also using Jersey and JAX-RS. Thank you for your help,
Maxi
If the file is inside the application WAR (or in a jar) you can try by using
InputStream input = servletContext.getClass().getClassLoader().getResourceAsStream("my_filename.txt");
Your problem is similar (I think) with How can I read file from classes directory in my WAR?
Try to get the path of the file from ServletContext.
ServletContext context = //Get the servlet context
In JAX-RS to get servlet context use this:
#javax.ws.rs.core.Context
ServletContext context;
Then get the file from your web application:
File file = new File(context.getRealPath("/someFolder/myFile.txt"));
You don't post the code that actually tries to read the file, but assuming the file is in the classpath (as you mention it's in the same directory as the class) then you can do:
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
See here