Servlet 404

I have an HTML form in a JSP file in my WebContent/jsps folder. I have a servlet class servlet.java in my default package in src folder. In my web.xml it is mapped as /servlet.

I have tried several URLs in action attribute of the HTML form:

<form action="/servlet">
<form action="/servlet.java">
<form action="/src/servlet.java">
<form action="../servlet.java">

But none of those work. They all keep returning a HTTP 404 error like below:

HTTP Status 404

The requested resource (/servlet) is not available.

Why is it not working?

shareimprove this question
 
1  
BalusC has provided you a great answer. If still something is not working try updating your question with some code, so we can get a clue of what is going wrong. As the question is formulated only a magician with Servlet knowledge can figure out what's wrong – MaVRoSCy Jul 31 '12 at 5:49 

First of all, put the servlet class in a Java package (you should ALWAYS put publicly reuseable Java classes in a package, otherwise they are invisible to classes which are by itself in a package). This way you eliminiate potential environment-specific problems. In case of a "plain" IDE project, the class needs to be placed in its package structure inside "Java Resources" folder (and thus NOT "WebContent", this is for web files such as JSP). In case of a Maven project, the class needs to be placed in its package structure inside main/java (and thus NOT e.g. main/resources, this is for non-class files).

Second, the servlet's URL is specified as the "URL pattern" of the servlet mapping. It's absolutely not per definition the classname/filename of the servlet class.

So, given a servlet class like below,

package com.example;

public class YourServlet extends HttpServlet {
    // ...
}

the servlet registration in web.xml must look like this:

<servlet>
    <servlet-name>yourServlet</servlet-name>
    <servlet-class>com.example.YourServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>yourServlet</servlet-name>
    <url-pattern>/servlet</url-pattern>  <!-- This is the URL of the servlet! -->
</servlet-mapping>

Or, in case you're already on Servlet 3.0+ (Tomcat 7 or newer), and the web.xml file is declared conform Servlet 3.0+ (and thus NOT e.g. 2.5 or lower), then all of above XML code can be replaced by a single @WebServlet annotation whose value represents the URL pattern.

package com.example;

@WebServlet("/servlet") // This is the URL of the servlet!
public class YourServlet extends HttpServlet {
    // ...
}

As to your concrete problem with the HTML <form>, the <form action> needs to be a valid URL. You need to understand how absolute/relative URLs work. You know, an URL is a web address as you can enter/see in the webbrowser's address bar. If you're specifying a relative URL as form action, i.e. without the http:// scheme, then it becomes relative to the current URL as you see in your webbrowser's address bar. It's thus absolutely not relative to the JSP/HTML file location in server's WAR folder structure as many starters seem to think.

So, provided that a webapp is successfully deployed on a context path of /contextname, and the servlet hasn't failed its initialization (read server logs for any deploy/servlet success/fail messages and the actual context path and servlet mapping), then this servlet is available at http://localhost:8080/contextname/servlet.

So, assuming that the JSP page with the HTML form is opened by http://localhost:8080/contextname/jsps/page.jsp, here are several cases:

  1. Form action submits to an URL with a leading slash.

    <form action="/servlet">

    The leading slash / makes the URL relative to the domain, thus the form will submit to

    http://localhost:8080/servlet

    But this will likely result in a 404 as it's in the wrong context.

  2. Form action submits to an URL without a leading slash.

    <form action="servlet">

    This makes the URL relative to the current folder of the current URL, thus the form will submit to

    http://localhost:8080/contextname/jsps/servlet

    But this will likely result in a 404 as it's in the wrong folder.

  3. Form action submits to an URL which goes one folder up

    <form action="../servlet">

    This will go one folder up (exactly like as in local disk file system paths!), thus the form will submit to

    http://localhost:8080/contextname/servlet

    This one must work!

The canonical approach, however, is to make the URL domain-relative so that you don't need to fix the URLs once again when you happen to move the JSP files around into another folder.

<form action="${pageContext.request.contextPath}/servlet">

This will generate

<form action="/contextname/servlet">

which will thus always submit to the right URL.

See also:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章