JSP Tomcat Bad Resources - java

We are deeper into our project, and have set up a basic web application with eclipse. Whenever we attempt to run the server, we get a 404 error like the following
From my research, I have found I need some sort of web.xml file. Where should put this file what should be in it. How do I make it

Your problem is your trying to access a resource within the WEB-INF folder, that is not allowed and that is the reason you have this error, you must put the jsp under the WebContent folder or any folder under the WebContent folder.
The WEB-INF\classes contains the .class files for your Java classes and it's not a good place to put any resource.
Since the 3.0 specification for servlets the web deployment descriptor (web.xml) is optional.
I hope this could help you to fix your problem

Putting JSPs under WEB-INF makes them inaccessible unless you map them in WEB.XML The purpose of WEB-INF is to hide things because users cannot download or access anything under WEB-INF. You only put JSPs under WEB-INF if you don't want the user to be able to go there by its real name (i.e. http://localhost/app/whatever.jsp) but want to map it to some specific url (i.e. http://localhost/app/somename/)
Mapping a JSP that is under WEB-INF to a URL cane be done with this in the WEB.XML
<servlet>
<servlet-name>somename</servlet-name>
<jsp-file>/WEB-INF/whatever.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>somename</servlet-name>
<url-pattern>/somename/*</url-pattern>
</servlet-mapping>
Of course, if you need to map another URL to the JSP but don't feel the need to disallow the user from going there by its .jsp filename, you can use a URL Rewriting filter for that. In that case, there is no point in putting it under WEB-INF.

Related

Java Servlet - Mapping a servlet to every URL but a string

I have a servlet configured to handle all URLs (*):
<servlet>
<servlet-name>MyServ</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServ</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
I need that for URLS beginning with /static/, it should serve them from the static WEB-INF. That is, MyServ should serve everything but /static.
How can I do that?
UPDATE: To clarify, what I'd like is:
/*/ - Goes to MyServ
/static/dir/file.css - Jetty serves the static file.css from the /dir/.
I'm not sure what web.xml to do, or where to put the static files.
I tried adding this:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
But, when I go to a /static/ URL, I just get:
HTTP ERROR 404
Problem accessing /static/dir/file.css. Reason:
Not Found
Powered by Jetty://
I'm not sure if my web.xml is wrong, or if I'm simply putting the files in the wrong place (I've tried under src/main/webapp and src/main/webapp/lib/META-INF/resources/)
Jetty
I am using Jetty. I want to avoid any other layers, such as Nginx, Apache, etc.
To win the bounty, please make sure you answer works for Jetty.
Your best bet is probably to have a rule for static that occurs before the rule for *.
Rule for URL path mapping:
It is used in the following order. First successful match is used with no further attempts.
The container will try to find an exact match of the path of the request to the path of the servlet. A successful match selects the servlet.
The container will recursively try to match the longest path-prefix. This is done by stepping down the path tree a directory at a time, using the ’/’ character as a path separator. The longest match determines the servlet selected.
If the last segment in the URL path contains an extension (e.g. .jsp), the servlet container will try to match a servlet that handles requests for the extension. An extension is defined as the part of the last segment after the last ’.’ character.
If neither of the previous three rules result in a servlet match, the container will attempt to serve content appropriate for the resource requested. If a “default” servlet is defined for the application, it will be used.
So it will match the rule for /static/, and stop there.
Your problem can by solved using the Nginx. Nginx serves static content HTML files, images (.jpg, .png, .gif), stylesheets (.css) and JavaScript (.js). These files need not to be processed by the web server. Nginx will do this job.
server {
listen 80;
server_name YOUR_DOMAIN;
root /PATH/TO/YOUR/WEB/APPLICATION;
location / {
index index.jsp;
}
location ~ \.jsp$ {
proxy_pass http://localhost:8080;
}
location ^~/servlets/* {
proxy_pass http://localhost:8080;
}
}
To serve static content you dont even need to have a servlet. You can put your static content in a folder which is directly accessible through your server.
For example if your application name is TestApp than you can place your content in TestApp/static/dir directory. Based on that your directory structure would be :
TestApp
|
|_____ WEB-INF
|
|_____ static
|
|____ dir
By doing above directory structure all your static content e.g. Sample.css will be accessible through below URL:
/TestApp/static/dir/Sample.css
Please look at this question for more information How to serve static content from tomcat
Note that by doing this your static directory will be open to everyone without any restriction which means anyone will be able to access your static content without any authentication. But as its your static content I guess its fine unless you have any reason for it.
First, files that are located in "WEB-INF" directory aren't directly web accessible.
Also, I noticed that your entry "src/main/webapp/lib/META-INF/resources/" does not include a extracted WAR directory, aka web application folder.
Example:
src/main/webapp/[WAR folder]/lib/META-INF/resources/
I assumed that you are using Tomcat. So, after you create your WAR file drop it into "webapp" directory, then start Tomcat. The WAR file should extract into a web application folder of the same name as the WAR file. Now from a browser you should has access to any files outside of "WEB-INF".
example: localhost:8080/[web app folder name]/[some file]
Hope this helps,
Simply put your static content into webapp Directory.
That part can be directly access. using localhost:port/yourAppName/ResourceName
Based on my experience (as already suggested by Srinivasu Talluri), reverse proxy is the answer to your problem.
You could use Nginx See detail configuration or configure Apache to work as reverse proxy.
Detail configuration for serving static content thru Nginx could be find here
When static contents will be handled by the web server itself, then your servlet configuration could be used as is. Thus your servlet will serve only the dynamic resources.
Hope it helps.

How to access my web application with and without / at the end of the URL

In my opinion I have a very simple problem, but I am not able to figure out a working solution.
I have been following web.xml
<servlet-mapping>
<servlet-name>Servlet</servlet-name>
<url-pattern>/article/*</url-pattern>
</servlet-mapping>
If I access my web application from following url http://localhost/article everthing works fine. If I add a slash at the end, the application run into an ifinitie loop.
I knew this is produced by the getRequestDispatcher("index.jsp").forward(req, resp) call and the web.xml configuration entry /article/*.
If I change index.jsp to /index.jsp, I get forwarded correctly, but all resources are sill mapped to the wrong path. For example, the css files are mapped to article/css instead of css. I think this happens because the getRequestDispatcher, keeps the contextPath.
The index.jsp is placed in the root directory.
How could I access http://localhost/article and http://localhost/article/?
I assume that:
the static resources are relative to the JSP on your file system
the URLs are relative
The browser is going to resolve relative URLs relative to the current URL. You can use the application's context path to provide the correct path:
<link rel="stylesheet"
href="${pageContext.servletContext.contextPath}/css/foo.css">
Now it doesn't matter what the request URL is or what the application context path is; the links will be resolved correctly.
The expression is a bit verbose but you could always shorten it with an application-scoped copy of the string.

servlets couldnt accessible from webapplication in linux

I have deployed Myapplication.war in tomcat webapps directory.
now i have, index.jsp in $CATALINAHOME/webapps/Myapplication and process.class in $CATALINAHOME/webapps/Myapplication/WEB-INF/classes.
When index.jsp post some variables to process, http://x.x.x.x:8080/Myapplication/process
Im getting below err,
type Status report
message /Myapplication/process
description The requested resource is not available..
if i convert the process file from java class to jsp, im able to post from index.jsp to process.jsp.
How can i achieve this? any other settings i need to do here?
Thanks in advance
You'll have to declare your servlet in web.xml otherwise Tomcat won't know which class to associate with which path:
<servlet>
<servlet-name>processServlet</servlet-name>
<servlet-class>process</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>processServlet</servlet-name>
<url-pattern>/process</url-pattern>
</servlet-mapping>
See also the tomcat sample deployment descriptor
A couple of minor niggles:
As per Java class naming, classes should start with an uppercase character, so it would be Process and Process.java.
Usually it makes more sense to put java classes into a package.

How to put jsp in ROOT folder of tomcat so that the jsp is picked by all web apps

I have multiple web applications defined in my tomcat. In case of any exception, I want to throw one jsp (done using SimpleMappingExceptionResolver tag of spring). When I put the jsps in the web-inf folder of the web applications, it works fine which is obvious.
But I want to put this jsp at a common place in tomcat such as ROOT library. But if I do this, tomcat is not able to find my jsp. Can somebody tell me if any changes in web.xml is required to make this happen or I should put this jsp somewhere else.
Thanks in advance.
What do you mean by 'picked up' or 'access'? You can put a jsp file on the tomcat ROOT application, and do a 302 redirect into it everytime you encounter exception.
For example place you all-apps generic exception page on webapps/ROOT/generic_exception.jsp, then on each of your apps, add this to the web.xml
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/myapp_error.jsp</location>
</error-page>
That should redirect request into myapp_error.jsp (inside myapp) if any uncaught exception surfaces. Then inside myapp_error.jsp, just perform html meta redirect to /generic_exception.jsp
However the drawback of this approach is you are redirected into different web-app, it's difficult / require extra work if you want to pass session attributes

Jnlp-Prevent downloading of the jars that i referenced

I have been developed a jnlp file, and it is working properly when client downloads it from his/her browser. No problem up to here, but client can also access to the jar files that my jnlp is referencing, and eventually download them.
I don't want my jars to be downloaded by others by writing the path from browser. I just want to make the jnlp is directly accessible from browser.
How can I fix this situation ?
There is no 'fix' for it. If the Jars are accessible to the JWS client that launches the app., they are also available by direct fetch.
You can use the provided JnlpDownloadServlet as a way to block access. The JnlpDownloadServlet (look for it in the samples provided with the JDK) will handle requests for Jar files and do a diff on them. If you setup your web.xml file like
<servlet>
<servlet-name>JnlpDownloadServlet</servlet-name>
<servlet-class>com.sun.javaws.servlet.JnlpDownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>JnlpDownloadServlet</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
then all requests for the files in /app will go through this servlet. This will prevent users from doing a simple browse to see the available files, but if they know the file name they can still create a get request to fetch it through the servlet.
If that is a problem, then you can also put security on access to this servlet (as you would any other servlet) using the security-constraint settings in the web.xml. If you add that, then the javaws launcher will require the user to provide valid credentials before it will download the files. I used BASIC as the auth-method because I wasn't sure if the javaws client would honor any others.
What if you generate the jnlp dynamically via a JSP or servlet (see here an example)?
In this case you can write a filter that can implement a policy(based on a cookie?) for retrieving files. If the cookie is not set you can disable the download of jars.
See the following article: http://lopica.sourceforge.net/faq.html#cookies

Categories