I'm using a standard maven archetype of webapp, so I put my images folder under src/main/resources directory and in the war package it goes under WEB-INF/classes/ directory.
My project tree is in the following image
So the images dir is in the classpath and i load it via getResource
final String path ="/resources/images/disegno.svg";
URL imagePath = this.getClass().getClassLoader().getResource(path);
but i get
Could not complete request
java.lang.NullPointerException
when declaring path
Also in .jsp, I try to access the image in this way:
<img src="<%=request.getContextPath() %>/WEB-INF/classes/images/disegno.svg"/>
but no image is displayed, even if it links to
http://localhost:8080/svgTest/WEB-INF/classes/images/disegno.svg
I cannot understand how maven works in this situation, and cannot find a complete guide, because everywhere all looks so easy, so I don't know which error i'm doing...
You're making 3 mistakes.
First: ClassLoader.getResource() expects a path that does NOT start with a /.
Second: what is under src/main/resources in the source project goes at the root of the classpath. There is no resources package, as your screenshot of WEB-INF/classes shows. So your path should be
this.getClass().getClassLoader().getResource("images/disegno.svg")
Third: by design, everything undex WEB-INF is not accessible from the browser. Everything out of WEB-INF is. So if you want the browser to be able to download your image, it should be in the src/main/webapp folder, not in src/main/resources. Of cource, once it's there, you won't be able to load it with the ClassLoader anymore, since it won't be in the classpath anymore. If you need to load it in addition to make it directly available to the browser, then use ServletContext.getResource().
Related
I'm making a java web app, and I want it to display an image. However, it doesn´t find my image.
I've made a folder in /src/main/resources/images
Also, in the .jsp file, I´ve tried with the following sentences.
<img src="/src/main/resources/images/Head.png"> </img>
<img src="< c:url value='/src/main/resources/images/Head.png'/>"> </img>
Is there anything bad I'm doing?
Thanks
Edit:
The path of mi .jsp file is /src/main/webapp/WEB-INF/jsp/welcome.jsp
You can find the web app code in https://github.com/Santi-7/hello
Your app is a Spring Boot app. I think that you can also try to use the facilities provided by Spring Boot for serving static content. Anyway, you are doing it right now because you are using webjars for css and js libs!!! Be consistent with the tech that you are using.
The structure of a .war file is as follows:
/
/WEB-INF
/lib
/classes
/META-INF
Now, your application has the following structure (I assume, given the folder structure, you are using Maven)
/
/src
/main
/java
/resources
/webapp
Now, the Maven war plugin will copy everything in the classpath to /WEB-INF/classes during compilation - this is /src/main/java and /src/main/resources by default.
The crux of the matter is that nothing under /WEB-INF or /META-INF can be accessed by requests - this is for security as otherwise someone could simply download /WEB-INF/web.xml for example.
So, in order to add a resource that is accessible by a browser, you need to place it into /src/main/webapp - this will become the root of the application.
So if you place Head.png into /src/main/webapp/images then in the JSP you would use:
<c:url value='/images/Head.png'/>
In short, you need to read up on how the directory structure of a .war works and how that relates to your code.
The path to the image must be relative to the path to the .jsp file.
Because the path to your image is: /src/main/resources/images/Head.png, and the path to your jsp file is: /src/main/webapp/WEB-INF/jsp/welcome.jsp, in your image tag you need to write:
<img src="../../../resources/images/Head.png" />
The ../../../ is for getting out from the jsp folder to the main folder, and the resources/images/Head.png is the path from the main folder to the image.
Thanks everybody, i could resolve my problem.
Changes I made:
So, in order to add a resource that is accessible by a browser, you need to place it into /src/main/webapp - this will become the root of the application.
Now, my images are in /src/main/webapp/images.
The path to the image must be relative to the path to the .jsp file.
Now, the sentence of my .jsp file is
<img src="images/Head.png" />
Edit [1]:
¡ I made a mistake. The path to the image is relative to the /webapp classpath !
I have in the resources of my Maven project an index.html file in the res/html folder.
I am running Jetty as an embedded webserver. I want to tell him that the base resource for static content is the res/ folder.
So, I tried:
ResourceHandler rh = new ResourceHandler();
rh.setResourceBase(getClass().getResource("/res").toURI().toString());
It worked until I included another jar on my classpath which also have a res/ folder.
Jetty started to look for static content in thisotherjar.jar!res/
I would like to avoid having to give literally the path of the jar that contains my res folder. I am looking for something more generic. I tried to start with the classpath of the file index.html and then go up the the res folder using URI.resolve("..") but the same problem happens.
Any ideas to solve this nicely?
Thanks!
You should use a name that is less prone to collisions, exactly like for the Java packages. You do not name a package res because if everyone did that there would be conflicts every time we incorporate two libs.
Instead of the res directory give it a name that is specific to you such as com/mycompany/myproject/res.
I want to get the path to a resource for ImageIO to read out a BufferedImage from some .png s.
While developing the project I use a relative path to "/bin/stuff/icons/image.png" , but this will definetly not work when I put everything together into a .jar file, so I need a way to get the path to these resources both while testing in eclipse and when later running it within a .jar .
After a lot of trying out both finding the file and getting the input stream to the file I came to the conclusion that this approach works every time:
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(path)
BufferedImage image = ImageIO.read(in)
Where path is
"projectName/resourceFolder/" + nameOfResource.stuff
as found in the src directory of the eclipse project.
E.g.
"myProject/images/icon.png"
When getting only the resource and then getting the path of the resource to link to a file, you will get FileNotFoundExceptions when using a .jar (but not while testing with eclipse, so one should be warned to think that his code works).
And - no - I don't save images in the bin/ - but they are copied to this directory and thus I find them there while testing. Now everything seems to be working.
Don't put anything under the bin directory in Eclipse: if you run a clean on the project it will be erased.
What you can do is to define a new source folder like resources, and put the image there. This way it will be automatically copied to the bin folder.
If you include the resources folder into the Jar, it will be available in both environments by using something like:
ImageIO.read( getClass().getResource("/image.png") )
PS: You can evade using a different resources folder but mixing the sources and images will quickly pollute your source folder.
How do I create a resource so that it is located in the resource folder of my project?
In the following, "test.txt" is a file I want to create, but the variable:url is null, so I can't get a path to the file I want to create.
URL url= HashArray.class.getResource("test.txt");
File file = new File(url.toURI());
The resource probably needs to be located in the resources folder because I need to bundle it with the code in the packaging phase.
This can't work, as resources is not a runtime location. It's a source location. If you try to put a file, and run your program the url wouldn't be null anymore. But it would point to your target/classes folder (ok there are quite a number of possiblities, depending how exactly you start it) However, in most cases it wouldn't be resources anymore...
There is not relation between the resource folder in maven and a resource in Java.
class.getResource finds a resource in the classpath, you are fine putting your txt file in the resources folder but in order to make it accessible at runtime you have to package it.
How to package resources
I'm working with a project that is setup using the standard Maven directory structure so I have a folder called "resources" and within this I have made a folder called "fonts" and then put a file in it. I need to pass in the full String file path (of a file that is located, within my project structure, at resources/fonts/somefont.ttf) to an object I am using, from a 3rd party library, as below, I have searched on this for a while but have become a bit confused as to the proper way to do this. I have tried as below but it isn't able to find it. I looked at using ResourceBundle but that seemed to involve making an actual File object when I just need the path to pass into a method like the one below (don't have the actual method call in front of me so just giving an example from my memory):
FontFactory.somemethod("resources/fonts/somefont.ttf");
I had thought there was a way, with a project with standard Maven directory structure to get a file from the resource folder without having to use the full relative path from the class / package. Any advice on this is greatly appreciated.
I don't want to use a hard-coded path since different developers who work on the project have different setups and I want to include this as part of the project so that they get it directly when they checkout the project source.
This is for a web application (Struts 1.3 app) and when I look into the exploded WAR file (which I am running the project off of through Tomcat), the file is at:
<Exploded war dir>/resources/fonts/somefont.ttf
Code:
import java.io.File;
import org.springframework.core.io.*;
public String getFontFilePath(String classpathRelativePath) {
Resource rsrc = new ClassPathResource(classpathRelativePath);
return rsrc.getFile().getAbsolutePath();
}
In your case, classpathRelativePath would be something like "/resources/fonts/somefont.ttf".
You can use the below mentioned to get the path of the file:
String fileName = "/filename.extension"; //use forward slash to recognize your file
String path = this.getClass().getResource(fileName).toString();
use/pass the path to your methods.
If your resources directory is in the root of your war, that means resources/fonts/somefont.ttf would be a "virtual path" where that file is available. You can get the "real path"--the absolute file system path--from the ServletContext. Note (in the docs) that this only works if the WAR is exploded. If your container runs the app from the war file without expanding it, this method won't work.
You can look up the answer to the question on similar lines which I had
Loading XML Files during Maven Test run
The answer given by BobG should work. Though you need to keep in mind that path for the resource file is relative to path of the current class. Both resources and java source files are in classpath