I'm trying to use ServletContext.getResource to retrieve a java.net.url reference to an image file (which I will then include in a PDF library using iText).
When I use ServletContext.getRealPath("picture.jpg"), I get back a string URL. However, getResource always returns null.
Example 1:
String picture = ServletContext.getRealPath("picture.jpg");
// picture contains a non-null String with the correct path
URL pictureURL = ServletContext.getResource(picture);
// pictureURL is always null
Example 2:
URL pictureURL = ServletContext.getResource("picture.jpg");
// pictureURL is always null
So what is the correct way to build a java.net.URL object pointing to a file in my webapps/ folder? Why does getRealPath work but not getResource?
In case it helps at all, here is my folder structure
webapps -> mySite -> picture.jpg
Does my picture need to be stored in either WEB-INF or WEB-INF/classes to be read by getResource?
Returns a URL to the resource that is mapped to a specified path. The path must begin with a "/" and is interpreted as relative to the current context root.
So you must provide the context-relative full path. For example:
URL pictureURL = servletContext.getResource("/images/picture.jpg");
(note the lower-cased servletContext variable)
getRealPath() provides the operating specific absolute path of a resource, while getResource() accepts a path relative to the context directory, and the parameter must begin with a "/". Try ServletContext.getResource ("/picture.jpg") instead.
Doc:
getResource
Related
When I try and load a image from a resource directory in eclipse I keep getting a null pointer exception (NPE).
The res folder is in the project directory.
This where I get the NPE:
image.setIcon(new ImageIcon(new ImageIcon(this.getClass().getResource("res/bg.jpg")).getImage().getScaledInstance(image.getWidth(), image.getHeight(), Image.SCALE_SMOOTH)));
When I remove the getClass().getReource() the image is returned:
image.setIcon(new ImageIcon(new ImageIcon(("res/bg1.jpg")).getImage().getScaledInstance(image.getWidth(), image.getHeight(), Image.SCALE_SMOOTH)));
When I print the URL for the res directory I get null:
URL resource = this.getClass().getResource("/");
resource.getFile(); // print me somehwere
URL resource1 = this.getClass().getResource("/res");
resource.getFile(); // print me as well
URL resource2 = this.getClass().getResource("res/bg2");
resource.getFile(); // print me as well
System.out.println("Reource1 : " + resource);
System.out.println("Reource1 : " + resource1);
System.out.println("Reource1 : " + resource2);
Output:
Reource1 :file:/C:/Users/cmooney/eclipse-workspace/TextSimplifier/bin/
Reource1 : null
Reource1 : null
I have refreshed, cleaned, and built the project several times.
Directory:
Any idea why this is happening?
Thanks
Replace this.getClass().getResource("res/bg.jpg") with this.getClass().getResource("../res/bg.jpg")
Since this.getClass().getResource("/") returns file:/C:/Users/cmooney/eclipse-workspace/TextSimplifier/bin/, you need to go one level(directory) up in the directory structure so that you can enter the res directory. It's like cd ../res from the current location of file:/C:/Users/cmooney/eclipse-workspace/TextSimplifier/bin/
Note: I can't see bg.jpg in the screenshot that you have attached. Make sure, you have bg.jpg in this path.
From the official java doc: https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getResource-java.lang.String-
Finds a resource with a given name. The rules for searching resources associated with a given class are implemented by the defining class loader of the class. This method delegates to this object's class loader. If this object was loaded by the bootstrap class loader, the method delegates to ClassLoader.getSystemResource(java.lang.String).
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').
I think, you got the directory structure wrong.
If '/' points to the bin directory, as shown by the output of your first resource, '/res' points to the res subdirectory of bin and not to the sibling in the parent directory of bin.
You need to either move the res directory or change the way the resolution of '/' works.
The rules for searching resources associated with a given class are
implemented by the defining class loader of the class.
from Java documentation
For maven based projects the resource directory is usually src/main/resources.
I created the method where I get an absolute path but when I debug I get an incorrect path to the file which should be uploaded.
So, the method where I get absolute path:
public String getFilePathByFormat(String filePath) {
File file = new File(filePath);
return file.getAbsolutePath();
}
Then I use this method in the general low-level method for uploading:
public void uploadFile(WebElement webElement, String filePath){
try {
webDriver.manage().timeouts().implicitlyWait(40, SECONDS);
webElement.sendKeys(getFilePathByFormat(filePath));
}catch (Exception e){
printErrorAndStopTest();
}
}
And when I debug and evaluate incorrect path gets:
E:\acceptance-tests\src\test\resources, BUT after disk name, one more folder should be - where the project located.
What's wrong and why getAbsolutePath doesn't build the correct path?
Thanks
There are two types of file path in file system.
1) An absolute path always starts from root element and contains complete directory list required to locate the file. For example, '/Users/username/filename.txt' on Unix systems or 'C:\Users\username\filename.txt' on Windows systems.
A relative path does not have any directory listing and needs to be combined with another path in order to access a file. For example, username/filename.txt is a relative path; Note that it does not have any forward or backward slashes at the beginning.
getAbsolutePath() returns the absolute path of a file and works like below.
File object is created with absolute pathname - This method simply returns the pathname provided to create the file. And in case of Windows System, drive name is appended at beginning by default if it is not present in absolute path name given.
File object is created using relative path - Here relative path name is made absolute by resolving it against the current user directory.
In this case, absolute path '/acceptance-tests/src/test/resources/test4.pdf' is passed; As mentioned for windows system, drive details are prefixed with given path and returned as absolute path.
To make it work, you can pass the relative path of file 'src/test/resources/test4.pdf' or just pass the file name 'test4.pdf'.
I have a little problem with Struts 2 when I try to get the context path :
ServletActionContext.getServletContext().getRealPath("\\WebContent\\resources\\img\\");
I got this path:
C:\Users\killian\workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\SiteWebAdministrable\WebContent\resources\imgicone.jpg
Why the exact source path ?
Because i need to upload and save images for an admin website to control background and without the actual path i cannot save images in the resources path...
So i save the path with the name and extension in the database (no problem), and i need to save the image in the resource directory (image problem...)
Can someone help me please ? Did i forgot something ?
This question is the answer ?
How do you get the project path in Struts 2?
servletContext.getServletContext().getRealPath("/resources/img/name_of_image.png")
So, passing the "/" to getRealPath() would return you the absolute disk file system path of the /web folder of the expanded WAR file of the project. Something like /path/to/server/work/folder/demo.war/ which you should be able to further use in File or FileInputStream.
Note that most starters don't seem to see/realize that you can actually pass the whole web content path to it and that they often use
String absolutePathToIndexJSP = servletContext.getRealPath("/") + "demo.png";
instead of
String absolutePathToIndexJSP = servletContext.getRealPath("/demo.png");
getRealPath() is unportable; you'd better never use it
Use getRealPath() carefully.
If all you actually need is to get an InputStream of the web resource, better use ServletContext#getResourceAsStream() instead, this will work regardless of the way how the WAR is expanded. So, if you for example want an InputStream of index.jsp, then do not do:
InputStream input = new FileInputStream(servletContext.getRealPath("/demo.png")); // Wrong!
But instead do:
InputStream input = servletContext.getResourceAsStream("/demo.png"); // Right!
Or if you intend to obtain a list of all available web resource paths, use ServletContext#getResourcePaths() instead.
Set<String> resourcePaths = servletContext.getResourcePaths("/");
I wanted the url of a resource in the following form
C:/Users/.../build/classes/jam/lena1.png
To achieve this I wrote the following code
System.out.println(getClass().getResource("lena1.png").getPath());
but it returns
/C:/Users/.../build/classes/jam/lena1.png
Why is the extra forward slash appearing before the url?
Regard that Class.getResource() returns a URL, and URLs are not only file paths: A URL involves a protocol, a host, a port, and a path. And it has its own notation and format.
What you are getting in your example is the path part of the URL, and the path always starts by a slash, according to RFC2396.
If you want to get a File from a URL, you could use new File(url.toURI())... assumming that the input URL is actually referencing a local file path.
Because it's a URL, not a filename.
The question itself is odd. What do you care what the path of the URL is?
Leading slash to denote the root of the classpath. Try this : System.out.println(getClass().getResource("/lena1.png").getPath());
use this
String s = (getClass().getResource("lena1.png").getPath()).substring(1);
System.out.println(s);
I need to get real path for file in my WebContent directory, so that framework that I use can access that file. It only takes String file as attribute, so I need to get the real path to this file in WebContent directory.
I use Spring Framework, so solution should be possible to make in Spring.
If you need this in a servlet then use getServletContext().getRealPath("/filepathInContext")!
getServletContext().getRealPath("") - This way will not work if content is being made available from a .war archive. getServletContext() will be null.
In this case we can use another way to get real path. This is example of getting a path to a properties file C:/Program Files/Tomcat 6/webapps/myapp/WEB-INF/classes/somefile.properties:
// URL returned "/C:/Program%20Files/Tomcat%206.0/webapps/myapp/WEB-INF/classes/"
URL r = this.getClass().getResource("/");
// path decoded "/C:/Program Files/Tomcat 6.0/webapps/myapp/WEB-INF/classes/"
String decoded = URLDecoder.decode(r.getFile(), "UTF-8");
if (decoded.startsWith("/")) {
// path "C:/Program Files/Tomcat 6.0/webapps/myapp/WEB-INF/classes/"
decoded = decoded.replaceFirst("/", "");
}
File f = new File(decoded, "somefile.properties");
you must tell java to change the path from your pc into your java project so
if you use spring use :
#Autowired
ServletContext c;
String UPLOAD_FOLDEdR=c.getRealPath("/images");
but if you use servlets just use
String UPLOAD_FOLDEdR = ServletContext.getRealPath("/images");
so the path will be /webapp/images/ :)
In situations like these I tend to extract the content I need as a resource (MyClass.getClass().getResourceAsStream()), write it as a file to a temporary location and use this file for the other call.
This way I don't have to bother with content that is only contained in jars or is located somewhere depending on the web container I'm currently using.
Include the request as a parameter. Spring will then pass the request object when it calls the mapped method
#RequestMapping .....
public String myMethod(HttpServletRequest request) {
String realPath = request.getRealPath("/somefile.txt");
...
You could use the Spring Resource interface (and especially the ServletContextResource): http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/core/io/Resource.html
This approach uses the resource loader to get the absolute path to a file in your app, and then goes up a few folders to the app's root folder. No servlet context required! This should work if you have a "web.xml" in your WEB-INF folder. Note that you may want to consider using this solely for development, as this type of configuration is usually best stored externally from the app.
public String getAppPath()
{
java.net.URL r = this.getClass().getClassLoader().getResource("web.xml");
String filePath = r.getFile();
String result = new File(new File(new File(filePath).getParent()).getParent()).getParent();
if (! filePath.contains("WEB-INF"))
{
// Assume we need to add the "WebContent" folder if using Jetty.
result = FilenameUtils.concat(result, "WebContent");
}
return result;
}
my solve for: ..../webapps/mydir/ (..../webapps/ROOT/../mydir/)
String dir = request.getSession().getServletContext().getRealPath("/")+"/../mydir";
Files.createDirectories(Paths.get(dir));
try to use this when you want to use arff.txt in your development and production level too
String path=getServletContext().getRealPath("/WEB-INF/files/arff.txt");