Introduction
This can have a lot of causes which are broken down in following sections:
- Put servlet class in a
package
- Set servlet URL in
url-pattern
@WebServlet
works only on Servlet 3.0 or newerjavax.servlet.*
doesn’t work anymore in Servlet 5.0 or newer- Make sure compiled
*.class
file is present in built WAR - Test the servlet individually without any JSP/HTML page
- Use domain-relative URL to reference servlet from HTML
- Use straight quotes in HTML attributes
Put servlet class in a package
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 in a package, such as the source code of the server itself. This way you eliminate potential environment-specific problems. Packageless servlets work only in specific Tomcat+JDK combinations and this should never be relied upon. In case you are clueless which package to pick, start with com.example
.
In case of a «plain» IDE project, the class needs to be placed in its package structure inside the «Java Sources» folder, not inside «Web Content» folder, which is for web files such as JSP. Below is an example of the folder structure of a default Eclipse Dynamic Web Project as seen in Navigator view (the «Java Sources» folder is in such project by default represented by src
folder):
EclipseProjectName
|-- src
| `-- com
| `-- example
| `-- YourServlet.java
|-- WebContent
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
In case of a Maven project, the class needs to be placed in its package structure inside main/java
and thus not main/resources
, this is for non-class files and absolutely also not main/webapp
, this is for web files. Below is an example of the folder structure of a default Maven webapp project as seen in Eclipse’s Navigator view:
MavenProjectName
|-- src
| `-- main
| |-- java
| | `-- com
| | `-- example
| | `-- YourServlet.java
| |-- resources
| `-- webapp
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
Note that the /jsps
subfolder is not strictly necessary. You can even do without it and put the JSP file directly in webcontent/webapp root, but I’m just taking over this from your question.
Set servlet URL in url-pattern
The servlet URL is specified as the «URL pattern» of the servlet mapping. It’s absolutely not per definition the classname/filename of the servlet class. The URL pattern is to be specified as value of @WebServlet
annotation.
package com.example; // Use a package!
import jakarta.servlet.annotation.WebServlet; // or javax.*
import jakarta.servlet.http.HttpServlet; // or javax.*
@WebServlet("/servlet") // This is the URL of the servlet.
public class YourServlet extends HttpServlet { // Must be public and extend HttpServlet.
// ...
}
In case you want to support path parameters like /servlet/foo/bar
, then use an URL pattern of /servlet/*
instead. See also Servlet and path parameters like /xyz/{value}/test, how to map in web.xml?
Do note that it’s considered a bad practice to use a Servlet URL pattern of /*
or /
in an attempt to have a «front controller». So do not abuse these URL patterns in an attempt to try to catch all URLs. For an in depth explanation see also Difference between / and /* in servlet mapping url pattern.
@WebServlet
works only on Servlet 3.0 or newer
In order to use @WebServlet
, you need to make sure that your web.xml
file, if any (it’s optional since Servlet 3.0), is declared conform Servlet 3.0+ version and thus not conform e.g. 2.5 version or lower. It should absolutely also not have any <!DOCTYPE>
line. Below is a Servlet 6.0 compatible one (which matches Tomcat 10.1+, WildFly 27+ (Preview), GlassFish/Payara 7+, etc) in its entirety:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0"
>
<!-- Config here. -->
</web-app>
And below is a Servlet 5.0 compatible one (which matches Tomcat 10.0+, WildFly 22+ (Preview), GlassFish/Payara 6+, etc).
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
>
<!-- Config here. -->
</web-app>
And below is a Servlet 4.0 compatible one (which matches Tomcat 9+, WildFly 11+, GlassFish/Payara 5+, etc).
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
>
<!-- Config here. -->
</web-app>
Or, in case you’re not on Servlet 3.0+ yet (e.g. Tomcat 6 or older), then remove the @WebServlet
annotation (and make sure you also remove all the wrong JAR files or Maven dependencies which incorrectly made it possible for you to successfully compile the code):
package com.example;
import javax.servlet.http.HttpServlet;
public class YourServlet extends HttpServlet {
// ...
}
And register the servlet instead in web.xml
like this:
<servlet>
<servlet-name>yourServlet</servlet-name>
<servlet-class>com.example.YourServlet</servlet-class> <!-- Including the package thus -->
</servlet>
<servlet-mapping>
<servlet-name>yourServlet</servlet-name>
<url-pattern>/servlet</url-pattern> <!-- This is the URL of the servlet. -->
</servlet-mapping>
Note thus that you should not use both ways. Use either annotation based configuarion or XML based configuration. When you have both, then XML based configuration will override annotation based configuration.
javax.servlet.*
doesn’t work anymore in Servlet 5.0 or newer
Since Jakarta EE 9 / Servlet 5.0 (Tomcat 10, TomEE 9, WildFly 22 Preview, GlassFish 6, Payara 6, Liberty 22, etc), the javax.*
package has been renamed to jakarta.*
package.
In other words, please make absolutely sure that you don’t randomly put JAR files of a different server in your WAR project such as tomcat-servlet-api-9.x.x.jar merely in order to get the javax.*
package to compile. This will only cause trouble. Remove it altogether and edit the imports of your servlet class from
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
to
import jakarta.servlet.*;
import jakarta.servlet.annotation.*;
import jakarta.servlet.http.*;
In case you’re using Maven, you can find examples of proper pom.xml
declarations for Tomcat 10+, Tomcat 9-, JEE 9+ and JEE 8- in this answer: How to properly configure Jakarta EE libraries in Maven pom.xml for Tomcat? The alternative is to downgrade the server to an older version, e.g. from Tomcat 10 back to Tomcat 9 or older, but this is clearly not the recommended way to go.
In case you’re using Spring instead of Jakarta EE, Spring 6 and Spring Boot 3 are the first versions to target Servlet 5.0 and therefore also the first versions to use the jakarta.*
package. Older versions still use the javax.*
package. Adjust your imports accordingly and make absolutely sure that you don’t have any conflicting libraries in your dependencies which incorrectly make it possible to still successfully compile against javax.servlet.*
. Using javax.servlet.*
must give a compilation error in projects targeted at at least Servlet 5.0+ (so, either Jakarta EE 9+ or Spring 6+ or Spring Boot 3+).
Make sure compiled *.class
file is present in built WAR
In case you’re using a build tool such as Eclipse and/or Maven, then you need to make absolutely sure that the compiled servlet class file resides in its package structure in /WEB-INF/classes
folder of the produced WAR file. In case of package com.example; public class YourServlet
, it must be located in /WEB-INF/classes/com/example/YourServlet.class
. Otherwise you will face in case of @WebServlet
also a 404 error, or in case of <servlet>
a HTTP 500 error like below:
HTTP Status 500
Error instantiating servlet class com.example.YourServlet
And find in the server log a java.lang.ClassNotFoundException: com.example.YourServlet
, followed by a java.lang.NoClassDefFoundError: com.example.YourServlet
, in turn followed by jakarta.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
.
An easy way to verify if the servlet is correctly compiled and placed in classpath is to let the build tool produce a WAR file (e.g. rightclick project, Export > WAR file in Eclipse) and then inspect its contents with a ZIP tool. If the servlet class is missing in /WEB-INF/classes
, or if the export causes an error, then the project is badly configured or some IDE/project configuration defaults have been mistakenly reverted (e.g. Project > Build Automatically has been disabled in Eclipse).
You also need to make sure that the project icon has no red cross indicating a build error. You can find the exact error in Problems view (Window > Show View > Other…). Usually the error message is fine Googlable. In case you have no clue, best is to restart from scratch and do not touch any IDE/project configuration defaults. In case you’re using Eclipse, you can find instructions in How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
Test the servlet individually without any JSP/HTML page
Provided that the server runs on localhost:8080
, and that the WAR is successfully deployed on a context path of /contextname
(which defaults to the IDE project name or the Maven build artifact file name, case sensitive!), 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 a servlet with URL pattern of /servlet
is available at http://localhost:8080/contextname/servlet
.
You can just enter it straight in browser’s address bar to test it invidivually. If its doGet()
is properly overriden and implemented, then you will see its output in browser. Or if you don’t have any doGet()
or if it incorrectly calls super.doGet()
, then a «HTTP 405: HTTP method GET is not supported by this URL» error will be shown (which is still better than a 404 as a 405 is evidence that the servlet itself is actually found).
Overriding service()
is a bad practice, unless you’re reinventing a MVC framework — which is very unlikely if you’re just starting out with servlets and are clueless as to the problem described in the current question See also Design Patterns web based applications.
Regardless, if the servlet already returns 404 when tested invidivually, then it’s entirely pointless to try with a HTML form instead. Logically, it’s therefore also entirely pointless to include any HTML form in questions about 404 errors from a servlet.
Use domain-relative URL to reference servlet from HTML
Once you’ve verified that the servlet works fine when invoked individually, then you can advance to HTML. As to your concrete problem with the HTML form, the <form action>
value needs to be a valid URL. The same applies to <a href>
, <img src>
, <script src>
, etc. 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, assuming that the JSP page with the HTML form is opened by http://localhost:8080/contextname/jsps/page.jsp
(and thus not by file://...
), and you need to submit to a servlet located in http://localhost:8080/contextname/servlet
, here are several cases (note that you can here safely substitute <form action>
with <a href>
, <img src>
, <script src>
, etc):
-
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 tohttp://localhost:8080/servlet
But this will likely result in a 404 as it’s in the wrong context.
-
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.
-
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.
Use straight quotes in HTML attributes
You need to make absolutely sure you’re using straight quotes in HTML attributes like action="..."
or action='...'
and thus not curly quotes like action=”...”
or action=’...’
. Curly quotes are not supported in HTML and they will simply become part of the value. Watch out when copy-pasting code snippets from blogs! Some blog engines, notably WordPress, are known to by default use so-called «smart quotes» which thus also corrupts the quotes in code snippets this way. On the other hand, instead of copy-pasting code, try simply typing over the code yourself. Additional advantage of actually getting the code through your brain and fingers is that it will make you to remember and understand the code much better in long term and also make you a better developer.
See also:
- Our servlets wiki page — Contains some hello world examples
- How to call servlet class from HTML form
- doGet and doPost in Servlets
- How do I pass current item to Java method by clicking a hyperlink or button in JSP page?
Other cases of HTTP Status 404 error:
- HTTP Status 404 — Servlet [ServletName] is not available
- HTTP Status 404 — The requested resource (/ProjectName/) is not available
- HTTP Status 404 — The requested resource (/) is not available
- JSP in /WEB-INF returns «HTTP Status 404 The requested resource is not available»
- Referencing a resource placed in WEB-INF folder in JSP file returns HTTP 404 on resource
- Browser can’t access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP
This error indicates that the server could not find the desired resource. This resource can be any file such as JSP, HTML, or image resource. Usually, the resource is present, but it is referenced incorrectly. In most cases, you can fix this by correcting the URL. Here are three strategies you can use to look for errors:
- Java servlets do not handle URL
- Servlet forwarding the resource does not exist
- URL is case-sensitive
1. Java servlets do not handle URL
Your @Webservlet()
may handle for URL/name; however, the URL requested may be URL/this_name (different reference). You can fix this by correcting the reference URL or URL mapping.
In code, it may look something like this:
@WebServlet("/name")
public class Name extends HttpServlet {
...
}
However, your website requested /this_name
instead of /name
. One way you can correct this is by changing /name
to /this_name
in your URL mapping.
2. Servlet forwarding the resource does not exist
Make sure that the forwarded resource exists. If the resource you are trying to reference is not named correctly, you may also run into this problem. For instance, you are referencing signupForm.jsp
, but the name of the resource is signup_Form.jsp
. In code it may look something like this:
String signupForm= "frontend/signupForm.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(signupForm);
dispatcher.forward(request, response);
You can fix this by correcting the servlet’s path which, in this case, would be to change signupForm.jsp
to signup_Form.jsp
.
3. URL is case-sensitive
If you typed the URL yourself, you might have mistyped it. Tomcat URLs are case-sensitive. For instance, signup
is different than signUp
. Make sure your URL is case-sensitive.
Error 404: The requested resource is not available is a common issue when working with Java servlets, particularly the HelloWorld servlet. The error occurs when the server is unable to find the requested resource, which can be caused by several factors, including incorrect URLs, incorrect mapping of servlets in the deployment descriptor, and incorrect file paths. In this article, we will discuss the methods to fix the Error 404: The requested resource is not available using HelloWorld servlet.
Method 1: Check the URL
To fix the Error 404: The requested resource is not available using the HelloWorld servlet in Java, you can check the URL to ensure it matches the servlet mapping in your web.xml file. Here’s an example:
- Open your web.xml file and look for the servlet-mapping tag. It should look something like this:
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
-
Make sure the URL you are using to access the servlet matches the url-pattern in the servlet-mapping tag. In this example, the URL should be http://localhost:8080/your-web-app/hello.
-
If the URL is correct, check that the servlet class is properly defined in your web.xml file. It should look something like this:
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>com.example.HelloWorldServlet</servlet-class>
</servlet>
-
Make sure the servlet class is located in the correct package and that the package name is spelled correctly in your web.xml file.
-
Finally, make sure your server is running and that you have deployed your web application to the server.
Here’s an example of a HelloWorldServlet that you can use to test your setup:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorldServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
}
Make sure this class is located in the correct package and that the package name is spelled correctly in your web.xml file. Also, make sure you have compiled this class and that the compiled class file is located in the correct directory in your web application.
By following these steps and checking the URL, you should be able to fix the Error 404: The requested resource is not available using the HelloWorld servlet in Java.
Method 2: Verify Servlet Mapping
If you are encountering the «Error 404: The requested resource is not available» when trying to access your HelloWorld servlet, it could be due to incorrect servlet mapping. Here’s how to verify your servlet mapping:
- Open your web.xml file and check the servlet-mapping element for your HelloWorld servlet. It should look like this:
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
-
In the above example, the servlet-name is «HelloWorldServlet» and the url-pattern is «/hello». Make sure that the servlet-name matches the one in your servlet definition and the url-pattern is correct.
-
If the servlet mapping is correct, check the URL you are using to access the servlet. In the above example, the URL should be «http://localhost:8080/yourapp/hello» where «yourapp» is the name of your web application.
-
If the URL is correct and the servlet mapping is correct, make sure that your servlet is deployed correctly and that there are no errors in your code.
Here’s an example of a HelloWorld servlet with correct servlet mapping:
@WebServlet(name = "HelloWorldServlet", urlPatterns = {"/hello"})
public class HelloWorldServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>Hello World!</h1>");
out.println("</body></html>");
}
}
In the above example, the servlet is mapped to the URL pattern «/hello» and the servlet-name is «HelloWorldServlet». Make sure that the @WebServlet annotation is correct and that the servlet class is in the correct package.
By following these steps, you should be able to verify your servlet mapping and fix the «Error 404: The requested resource is not available» when accessing your HelloWorld servlet.
Method 3: Check the File Path
To fix the Error 404: The requested resource is not available using HelloWorld servlet, we can check the file path. Here are the steps to do it:
-
Check if the servlet class is in the correct package. The package name should match the directory structure.
-
Check if the servlet mapping is correct in the web.xml file. The URL pattern should match the URL used to access the servlet.
-
Check if the servlet class is compiled and deployed in the correct directory. The class file should be in the WEB-INF/classes directory or in a jar file in the WEB-INF/lib directory.
-
Check if the server is running and the web application is deployed correctly.
Here is an example code for the HelloWorld servlet:
package com.example;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorld extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.getWriter().println("<h1>Hello World!</h1>");
}
}
Here is an example web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>com.example.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
In this example, the servlet class is in the com.example package and the servlet mapping is /hello. To access the servlet, we can use the URL http://localhost:8080/your-web-app/hello, where your-web-app is the name of your web application.
By checking the file path, we can ensure that the servlet class is in the correct location and the web.xml file is configured correctly. This can help to fix the Error 404: The requested resource is not available using HelloWorld servlet.
Method 4: Restart the Server
To fix the Error 404: The requested resource is not available using HelloWorld servlet, you can try restarting the server. Here are the steps to do it:
- Stop the server:
// code to stop the server
server.stop();
- Start the server:
// code to start the server
server.start();
- Deploy the HelloWorld servlet:
// code to deploy the HelloWorld servlet
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
ServletHolder holder = new ServletHolder(new HelloWorld());
context.addServlet(holder, "/hello");
- Test the servlet:
Open a web browser and enter the URL: http://localhost:8080/hello
Here is the complete code:
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class App {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
// Stop the server
server.stop();
// Start the server
server.start();
// Deploy the HelloWorld servlet
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
ServletHolder holder = new ServletHolder(new HelloWorld());
context.addServlet(holder, "/hello");
// Test the servlet
System.out.println("HelloWorld servlet is running at: http://localhost:8080/hello");
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<h1>Hello World!</h1>");
}
}
Hope this helps you fix the Error 404: The requested resource is not available using HelloWorld servlet with Restart the Server method.
I have a web application and I have a problem
If the web page does not exist in my application I have got the following error page
HTTP Status 404 - /myapplication/department/home.html
type Status report
message /myapplication/department/home.html
description The requested resource (/myapplication/department/home.html) is not available.
I want to forward user to the index page, if this problem happen , without he knows How to do that
asked Aug 21, 2011 at 18:48
Just specify the index page as 404 default error page in web.xml
.
<error-page>
<error-code>404</error-code>
<location>/index.jsp</location>
</error-page>
I assume that you are aware that this is bad for user experience and SEO? If it is for example a page which you have (re)moved, then you should rather create a filter which does a 301 redirect to the desired location.
answered Aug 21, 2011 at 18:50
BalusCBalusC
1.1m373 gold badges3611 silver badges3556 bronze badges
4
- Details
- Written by
- Last Updated on 05 November 2019 | Print Email
In Java web development with Tomcat, it’s very often that you get HTTP 404 error like this:
The error code is HTTP 404 (not found) and the description is:
The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
This error means the server could not find the requested resource (JSP, HTML, images…) and returns HTTP status code 404. Most of the time, you can fix this error by correcting the URL. However, sometimes it’s not easy like that, making it is an annoying error.
Here I suggest some possible reasons and how to fix the error HTTP 404 in Java web development with Tomcat.
1. The URL is not handled by any Java servlets
You need to check URL mapping in your servlet classes to make sure the requested URL is actually handled by a servlet. For example:
@WebServlet("/view_book") public class ViewBookServlet extends HttpServlet { ... }
This servlet handles the URL /view_book. If the request URL is /view_books the server will raise HTTP 404 error. You can fix by either correcting the URL or correcting the URL mapping in the @WebServlet annotation.
In older Java web application, you have to check the web deployment descriptor file web.xml because a Java servlet can be mapped to URL via XML like this:
<servlet-mapping> <servlet-name>ViewBookServlet</servlet-name> <url-pattern>/view_book</url-pattern> </servlet-mapping>
2. Java servlet forwarding to a resource that does not exist
In this case, the requested URL is handled by a Java servlet, but code in the servlet forwards to a resource (JSP, HTML…) which does not exist, as shown in the following screenshot:
The code in the servlet class would look like this:
String registerForm = "frontend/registerform.jsp"; RequestDispatcher dispatcher = request.getRequestDispatcher(registerForm); dispatcher.forward(request, response);
You can fix by correcting the forward path in the servlet, and make sure that the forwarded resource does actually exist in the given path.
3. URL is case-sensitive
Note that Tomcat treats URL as case-sensitive, for instance /Register is different than /register. So you need to check and use correct case for the letters in request URL.
Also pay attention to the webapp name in the URL, for instance http://localhost:8080/BookstoreWebsite/ is different than http://localhost:8080/BookStoreWebsite/
TIP: in Eclipse, you can right click on the project, then click Run As > Run on Server, the IDE will always use the correct name of the web application.
Finally, you should not let the user see the raw HTTP 404 error page rendered by the server. Instead, you should design your own user-friendly 404 error page – follow this tutorial: How to Handle Error for Java web applications.
You can also watch the video version below:
Other Java Servlet Tutorials:
- Java Servlet Quick Start for beginners (XML)
- Java Servlet for beginners (annotations)
- Java Servlet and JSP Hello World Tutorial with Eclipse, Maven and Apache Tomcat
- Handling HTML form data with Java Servlet
- Java File Download Servlet Example
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.