I am porting a web app to tomcat and I have a problem with static resources.
I have a jar that contains the web resources (css, img, js, ... files). These files are packaged in a path resembling this:
data.jar
com/bizname/application/web/css
com/bizname/application/web/img
com/bizname/application/web/js
The jar is inside the web application. I want to be able to map the resources to public acces. For example if I acces :
http://myserver:8080/mywebapp/css/style.css
I want the resource com/bizname/application/web/css/style.css to be delivered.
I cant find how to set up this in the web.xml-file of Tomcat.
In Jetty embedded, I was able to use handles to achieve this.
final URL url_css = Servidor.class.getClassLoader().getResource("com/bizname/application/web/css");
HandlerList handlers = new HandlerList();
handlers.addHandler(new WebAppContext(url_css.toExternalForm(),"/css"));
// ... adding handler to context
Maybe jawr can help you.
If not, you can implement a Servlet that does it for you (reading the file and writing it to the response). If you use something like Resteasy it will be easier because you don't need to write the IO stuff.
I am not quite sure this is right, considering I have only worked with Tomcat from Eclipse, but I'll give it a shot anyway.
I am assuming you are using Java Servlets in this app? If that is the case, then you need to specify the URL-patterns in web.xml. Here is a great example of a web.xml file from apache.org which explains the aspects of the file:
https://tomcat.apache.org/tomcat-5.5-doc/appdev/web.xml.txt
Hope this helps you!
Related
I am creating a REST based web application and using the latest version of Jersey and embedded Jetty. Descriptor-less deployment for Servlet 3.0 allows the exclusion of web.xml. However, I am having trouble understanding how you can serve static content in this case (.html, .css, .js and image files)? As the application is using embedded Jetty, I am not deploying this in a standalone servlet container, so the resulting file is a shaded .jar. Perhaps, I need to use the WAR plugin to make this possible? If so, where exactly do I have to place the aforementioned files? Is it still possible with packaging into .jar only as well?
The only way I have been able to serve static content so far, was with direct filesystem access, like this (Jersey's JAX-RS part):
#GET
#Path("manager/preview/img/loader.gif")
#Produces("image/gif")
public final Response preview() throws Exception
{
final byte[] b = Files.readAllBytes(Paths.get("manager/preview/img/loader.gif"));
return Response.ok().entity(b).build();
}
This definitely does not seem like the appropriate way. I'd be thankful, if someone could point me in the right direction.
How is it possible to restrict files(PDF) access in JSP/Glassfish so they can be opened only from a source code not with a straight url. For PHP projects I used .htaccess.
Anything under the webapp's WEB-INF directory cannot be accessed via direct URL, but application code can access it. This is a good place to put internal resources, config, JSPs, etc.
Wow,
.htaccess is an Apache HTTPD feature. As far as I know there isn't anything comparable in GlassFish. What you could do is: Write a Servlet or Servlet Filter which takes care of this and/or map the *.pdf extension in web.xml to it..
Thanks,
M
I got a situation that I must serve files from different folders then the one of the context my web app is running. As an example, suppose my web app is running in a servlet context on "/opt/tomcat/webapps/ROOT/" and I must serve files existent in "/opt/my_other_folder/". These folders can be changed in runtime by the client, so I can't simply add a new context pointing to these directories. I would like a solution that I wouldn't have to rewrite a web server only for that. Also, the product I work on is generic, so I can't have a solution specific to some servlet container.
Thanks!
If you're only serving files, I would consider fronting your servlet container with something like Apache HTTP Server, where you could simply use its various directives to provide a "virtual directory" pointing to an easily configured location.
Otherwise, you could write and configure a standard Java servlet that would do essentially the same thing - storing the actual path in a Java properties file that would be read by the servlet. But while this isn't a lot of work, it would be significantly more work that the above Apache HTTP Server solution. This would be very similar to several of the answers posted at Servlet for serving static content . Specifically, you could either use or extend upon Apache Tomcat's DefaultServlet. (There are some Tomcat-specific classes used in here, but they could be easily replaced with generic equivalents.) http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and.html looks even closer to what you'd be looking for, and it is completely generic - while still having some additional, significant features.
Either of these options would be very generic, and not specific to any particular servlet container.
I am trying to figure out what the following url does.
http://server/abc/testmodule/runtest.do?action=edit&id=123
I am new to jboss/jsp but I am very familiar with .net.
When I see this url, I expect to see the physical folder called "abc" and subfolder called "testmodule" and a physical file "runtest". am i wrong? what does runtest.do? is "runtest" class and "do" is a method within it?
It could be anything--URLs can map to arbitrary resources. It might be a Struts action, it might be a servlet, it might be a Spring controller, etc.
You'd need to check your web.xml file and/or any framework configuration files, or provide more information.
(Also, JBoss isn't a framework, it's a Java EE container :)
The /abc entry is the name of the context in which the application is running. If it's a web app, deployed in a WAR file, that would be the name of the WAR that's deployed (abc.war).
The .do extension suggests a Struts or JSF action mapping.
There are two parameters passed in the GET: action, with value edit, and id, with value 123. Looks like a REST-ful API to me.
I've managed to deploy a .war to the Jboss web container containing and read the pom.properties located under /META-INF/groupid-dir/artifactid-dir/
To access the file I've used the following code inside a JSP in the same war:
ServletContext servletContext = getServletConfig().getServletContext();
InputStream in = servletContext.getResourceAsStream("META-INF/maven/groupid-dir/artifactid-dir/pom.properties");
This works just fine. But I want to be able to dynamically read pom.propertes from ALL .war deployed in the container. Is this possible or do I only have access to the context for the one war holder my jsp?
-mb
Basically, your application is running on the same machine as the JBoss container, so accessing the files on the local filesystem should be possible, much in the same way you're accessing your own .properties file. I'm not familiar with anything that should prevent you from doing this.
If you want to access files within the war file, you'll need to use the java.util.zip package, as war files are of course normal zip files. Just a friendly reminder.
You will likely have to do something tricky like go through the JBoss MBeans. I realize this is vague, but consider looking into that approach. Here is a link on how to get the MBean server from an application within JBoss (add http://) www.jboss.org/community/wiki/FindMBeanServer (Stackoverflow is preventing me from pasting a link). I would imagine that you could find the Jboss Web mbean, peel off all web application mbeans, then ask each one for its classloader, then proceed to do what you already mentioned.
I don't think that reading a zip or using a jboss mbean are the right way.
I don't think it is tricky and you were on the right track by using ServletContext.getResourceAsStream.
You can probably use ServletContext.getResourcePaths, but several times it seems, to identify subdirectories groupid and artifactid.
Something like
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.properties")
or
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.xml")
for pom.xml
If the WAR file is exploded as folder , you should be able to use
String basePath=getServletContext().getRealPath("/");
This approach may not work if WAR file is in archive format
You can only look for resources in your current classpath. The normal operation of a web container is to create a specific classpath for each deployed artifact without access to the other artifacts deployed in the container.
This is very important to avoid artifact A which uses foo-1.0.jar to not accidentially use foo-0.9.jar which is deployed with artifact B.
Hence you will need ask the container for help. This in turn mean you need to write container specific code to do so. This will make you vendor dependent - you may not want that.