I want my servlet to receive files in some folder under the application directory tree. The server accepts files in multipart/form-data format. I've understood that #MultipartConfig is the right attribute to mark the servlet code, to allow the server to create files. However, not every location is considered as safe, hence two questions:
Which are the limitations, when specifying the locations for file-upload servlets
Can the paths be relative to application path or they should be absolute?
The files must be downloadable afterwards, so in general, which is a best place on the server to keep the files it (under the application tree, out of the tree, out of Tomcat tree etc?)
Since annotation seems to be a very 'static' way to allow servlet download things, can the same be specified in web.xml, for example?
Thanks!
1: Which are the limitations, when specifying the locations for file-upload servlets
It needs to be readable and writable. It also needs to be an existing location, the servletcontainer won't precreate it for you in case of absence.
2: Can the paths be relative to application path or they should be absolute?
Both are allowed, as long as 1) is confirmed. The container will under the covers use java.io.File to denote the location. So using relative paths is definitely a bad idea.
3: The files must be downloadable afterwards, so in general, which is a best place on the server to keep the files it (under the application tree, out of the tree, out of Tomcat tree etc?)
Putting in webapp folder will cause them all get lost whenever you redeploy the webapp. It also won't work on some server configs since extraction of the WAR file is an optional configuration setting. So it's really better to put them on a fixed path outside the webapp folder. To download them again, just add a new <Context> to Tomcat or create a servlet which gets a FileInputStream from it and writes to OutputStream of the response. Examples can be found in this answer.
4: Since annotation seems to be a very 'static' way to allow servlet download things, can the same be specified in web.xml, for example?
Yes, you can just ignore the location attribute of the annotation altogether and use Part#getInputStream() to write it to the desired location. You can then specify the location as <init-param> of the servlet and initialize it in init() method.
Related
I have a web application that contains hundreds of HTML, JavaScript and image files. These files are located under the root directory:
my_root--
-- html
-- js
-- images
These folders contain some subfolders.
From a security reason I need to move all these resources under the WEB-INF folder so they will not be directly accessible.
Currently JSP and servlet files are already under the WEB-INF folder.
What is the easiest method for me to safely move all HTML/JavaScript/images folders under the WEB-INF without breaking all links/forwarding to resources in these folders and make sure these resources are not directly accessible?
I am using WebSphere and WebLogic servers.
What is the easiest method for me to safely move all html/js/images folders under the WEB-INF without breaking all links/forwarding to resources in these folders and make sure these resources are not directly accessible?
You're making a thiniking mistake here. HTML/JS/image (and CSS) resources need to be directly accessible anyway. For JSPs the story is different, some of them, if not all, need to be preprocessed by a servlet (e.g. to retrieve some list from DB for display in a table). If those JSPs were been accessed directly, then that servlet step would be skipped altogether, which is absolutely not what you want (the JSPs end up "empty"; without any data from the DB). That's why they should be hidden in /WEB-INF to prevent direct access without going through a preprocessing servlet first. Also, in case of servlet based MVC frameworks, this way the whole MVC framework process (collecting request parameters, converting/validating them, updating model values, invoking actions, etc) would be skipped.
Your concrete functional requirement is not exactly clear (the whole question makes at its own no sense; the answer is just "don't do that"), but if you actually want to restrict access to static resources which don't need to be preprocessed by a servlet at all to certain users only, then you need to implement an authentication/login system. You can utilize container managed authentication or homegrow a Filter for this.
You can go with a very simple tool like notepad++ and use the findAndReplace feature. Eclipse can also do this but it gets tricky to effectively find every reference.
Note that there are other ways to stop users from accessing your images. It is probably easier to just leave things where they are and instruct the websphere to stop serving these images from the images folder
I setup a mapping to my images directory in Weblogic.xml by using the virtual-directory-mapping tag. How can I read the value of the real path so that my application can access that virtual directory for write access?
JMX seems to be of no help here since the WebServerMBean (or any other MBean) doesn't seem to provide access to the virtual-directory-mapping property.
Java Servlet API also has not yielded result since calling getRealPath() is only appending the url-pattern to the deployment directory of the application and not giving the correct path.
<virtual-directory-mapping>
<local-path>/home/wlsadm/images</local-path>
<url-pattern>help/specimens/*</url-pattern>
<url-pattern>*.xml</url-pattern>
</virtual-directory-mapping>
I've done a fair amount of research on this, reading vendor documentation, reading blogs, forums, etc. As the OP indicated, JMX use to be an approach to get this information, but this is no longer an option in current Weblogic versions.
The only solution I think you're left with is to create a utility that reads the information from the weblogic.xml file on the classpath. Something like an application listener that reads it on application startup and makes it available as a servlet attribute, etc.
Would love to hear how you solved it, though.
I am developing a java/javascript web application with JSPs, servlets, JAX-RS, and AngularJS. I am pretty new to this kind of stuff.
One problem I've been having is that I need to address url paths from static html, from javascript files, from jsps, and within servlets. I would like to be able to deploy this web app under different context roots (basically deploy in different folders). But in order to do this, unless I am mistaken, I must go through all the static files, (javascript and html) and change every link to properly reference resources based on new root directory. For the server side files, there are some java convenience methods like ServletContext's getContextPath() which allow me to avoid this.
Are there any conventions or strategies that people use to allow one to easily move a web app to different directories on a site without breaking all the links? At the moment I am guessing you must do search and replace for all the links.
Maybe put a special tag next to all local links so you know to change it?
Cheers,
As Java1 indicates, just use relative paths.
If the resource you are referencing is on the same level as the current web page, you don't need to prepend any path info. For example, if your main web page is loaded from path http://www.example.com/context/hello.html, and you have an image folder with path http://www.example.com/context/image, you can just load a image from that folder in your html with the relative path <img src="image/someimage.png">, without putting hostname or servlet context in your path.
If you are level deeper than the resource you are referencing, use "../" in front of the path. For example: <img src="../image/someimage.png">. If you are two levels deeper, use `../../image/someImage``, etc.
This holds true not just for images, but for scripts or static html as long as the web browser is loading the resource.
The web browser is responsible for converting the relative path to a server path. If you need to load something from the server side, you will need to use the full path.
I have my java application now i want to add security in my classes so that no one can de-compile my class files or open jar files.
i also want to add constraints in my web.xml file so that no one can try to access from another servlet.
I want to add security in my classes so that no one can de-compile my class files or open jar files.
You can't. It is mathematically impossible.
If someone can get hold of the JAR file / ".class" files, they can extract and decompile the classes. (There are ways to make it a bit harder ... but there is nothing you can do to stop a skilled and motivated attacker ... apart from not delivering code to him, in any form.)
I also want to add constraints in my web.xml file so that no one can try to access from another servlet.
Also impossible:
If you are talking about another servlet in the same web container, then anything you can put into the web.xml file can be edited out by the person who controls web container.
If you are talking about a servlet in another web container, then there is no way you can reliably distinguish a servlet making a request from a web browser making a request. All of the clues (e.g. request headers) can easily be spoofed.
My problem is one that you would think is quite common, but I haven't so far managed to find a solution.
Building a Java web app under Tomcat 5.5 (although a requirement is that it can be deployed anywhere, like under a WebLogic environment, hence the loading resources as streams requirement). Good practice dictates that resource files are placed under WEB-INF/classes and loaded using the ClassLoader's getResourceAsStream() method. All well and good when you know the name of the resource you want to load.
My problem is that I need to load everything (including recursively in non-empty sub-directories) that lives in a subdirectory of classes.
So, for example, if I have the following under WEB-INF/classes:
folderX/folderY
folderX/folderY/fileA.properties
folderX/fileB.properties
I need the fileA.properties and fileB.properties classes to be loaded, without actually knowing their names before the application is started (ie I need the ability to arbitrarily load resources from any directory under WEB-INF/classes).
What is the most elegant way to do this? What object could I interrogate to find the information I need (the resource paths to each of the required resources)? A non-servlet specific solution would be best (keeping it all within the class loading framework if possible).
Thanks in advance!
As far as I am aware, there is no such ability, since the classloader only attempts to load things it is asked for. It doesn't pre-fetch all items on the classpath, or treat them as a directory structure.
The way I would solve the problem is create a directory listing in a text file of all relevant resources at build time and include that in the war, and then walk it through that way.
You can do that with some tricks :)
Get the resource as URL, extract the protocol :
file protocol - get the URL path and you have a folder, scan for files.
jar/zip protocol - extract the jar/zip path and use JarFile to browse the files and extract everything under your path/package.