[html] Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"

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 in Tomcat 6/7/8:

HTTP Status 404 — /servlet

Description: The requested resource (/servlet) is not available.

Or as below in Tomcat 8.5/9:

HTTP Status 404 — Not Found

Message: /servlet

Description: The origin server did not find a current representation for the target resource or is not willing to disclose that one exists

Why is it not working?

This question is related to html forms jsp servlets http-status-code-404

The answer is


First of all, run your IDE as Admin. After that, right click the project folder -> Project Facets and make sure that the Java Version is set correct. On my PC. (For Example 1.8) Now it should work.

Don't just start your server, for example Wildfly, using the cmd. It has to be launched within the IDE and now visit your localhost URL. Example: http://localhost:8080/HelloWorldServlet/HelloWorld


Do the following two steps. I hope, it will solve the "404 not found" issue in tomcat server during the development of java servlet application.

Step 1: Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server

Step 2: Double Click on the server(in the server explorer tab)->Select Use tomcat installation option inside server location menu


Check if you have entered the correct URL Mapping as specified in the Web.xml

For example:

In the web.xml, your servlet declaration maybe:

<servlet>
        <servlet-name>ControllerA</servlet-name>
        <servlet-class>PackageName.ControllerA</servlet-class>
</servlet>

<servlet-mapping>
        <servlet-name>ControllerA</servlet-name>
        <url-pattern>/theController</url-pattern>
</servlet-mapping>

What this snippet does is <url-pattern>/theController</url-pattern>will set the name that will be used to call the servlet from the front end (eg: form) through the URL. Therefore when you reference the servlet in the front end, in order to ensure that the request goes to the servlet "ControllerA", it should refer the specified URL Pattern "theController" from the form.

eg:

<form action="theController" method="POST">
</form>

If you would like to open a servlet with javascript without using 'form' and 'submit' button, here is the following code:

var button = document.getElementById("<<button-id>>");
button.addEventListener("click", function() {
  window.location.href= "<<full-servlet-path>>" (eg. http://localhost:8086/xyz/servlet)
});

Key:

1) button-id : The 'id' tag you give to your button in your html/jsp file.

2) full-servlet-path: The path that shows in the browser when you run the servlet alone


Scenario #1: You accidentially re-deployed from the command line while tomcat was already running.

Short Answer: Stop Tomcat, delete target folder, mvn package, then re-deploy


Scenario #2: request.getRequestDispatcher("MIS_SPELLED_FILE_NAME.jsp")

Short Answer: Check file name spelling, make sure case is correct.


Scenario #3: Class Not Found Exceptions (Answer put here because: Question# 17982240 ) (java.lang.ClassNotFoundException for servlet in tomcat with eclipse ) (was marked as duplicate and directed me here )

Short Answer #3.1: web.xml has wrong package path in servlet-class tag.

Short Answer #3.2: java file has wrong import statement.


Below is further details for Scenario #1:


1: Stop Tomcat

  • Option 1: Via CTRL+C in terminal.
  • Option 2: (terminal closed while tomcat still running)
  • ------------ 2.1: press:Windows+R --> type:"services.msc"
  • ------------ 2.2: Find "Apache Tomcat #.# Tomcat#" in Name column of list.
  • ------------ 2.3: Right Click --> "stop"

2: Delete the "target" folder. (mvn clean will not help you here)

3: mvn package

4: YOUR_DEPLOYMENT_COMMAND_HERE

(Mine: java -jar target/dependency/webapp-runner.jar --port 5190 target/*.war )

Full Back Story:


Accidentially opened a new git-bash window and tried to deploy a .war file for my heroku project via:

java -jar target/dependency/webapp-runner.jar --port 5190 target/*.war

After a failure to deploy, I realized I had two git-bash windows open, and had not used CTLR+C to stop the previous deployment.

I was met with:

HTTP Status 404 – Not Found Type Status Report

Message /if-student-test.jsp

Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

Apache Tomcat/8.5.31

Below is further details for Scenario #3:


SCENARIO 3.1: The servlet-class package path is wrong in your web.xml file.

It should MATCH the package statement at top of your java servlet class.

File: my_stuff/MyClass.java:

   package my_stuff;

File: PRJ_ROOT/src/main/webapp/WEB-INF/web.xml

   <servlet-class>
   my_stuff.MyClass
   </servlet-class>

SCENARIO 3.2:

You put the wrong "package" statement at top of your myClass.java file.

For example:

File is in: "/my_stuff" folder

You mistakenly write:

package com.my_stuff

This is tricky because:

1: The maven build (mvn package) will not report any errors here.

2: servlet-class line in web.xml can have CORRECT package path. E.g:

<servlet-class>
my_stuff.MyClass
</servlet-class>

Stack Used: Notepad++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10:


The fix that worked for me is(if you are using Maven): Rightclick your project, Maven -> Update project. This might give you some other error with the JDK and other Libraries(in my case, MySQL connector), but once you fix them, your original problem should be fixed!


If someone is here who is using MySQL and felt that the code was working the previous day and now it doesn't, then I guess you must open MySQL CLI or MySQL Workbench and just make the connection to the database once. Once it gets connected, then the database also gets connected to the Java Application. I used to get the Hibernate Dialect error stating something wrong with com.mysql.jdbc.Driver. I think MySQL in some computers has a startup problem. This solved for me.


If you are a student and new to Java there might be some issue going on with your web.xml file.

  1. Try removing the web.xml file.
  2. Secondly check that your path variables are properly set or not.
  3. Restart tomcat server Or your PC.

Your problem will be surely solved.


Please check context root cannot be empty.

If you're using eclipse:
right click, select properties, then web project settings. Check the context root cannot be empty


Mapping in web.xml is what i have done :-

  1. If there's another package made for new program then we must mention :-

packagename.filename between opening and closing of servlet-class tag in xml file.

  1. If you are mapping your files in xml and they are not working or showing errors , then comment on the annotation line of code in the respective files.

Both methods dont work with one another , so either i use annotation method of files mentioned when we create servlet or the way of mapping , then i delete or comment the annotation line. Eg:

 <servlet>
   <servlet-name>s1</servlet-name>
   <servlet-class>performance.FirstServ</servlet-class>
   </servlet>    
   
   <servlet-mapping>
   <servlet-name>s1</servlet-name>
   <url-pattern>/FirstServ</url-pattern>
   </servlet-mapping>
   
   <servlet>
   <servlet-name>s2</servlet-name>
   <servlet-class>performance.SecondServ</servlet-class>
   </servlet>
   
   <servlet-mapping>
   <servlet-name>s2</servlet-name>
   <url-pattern>/SecondServ</url-pattern>
   </servlet-mapping>

Commenting the annotation line of code in the respective file,if mapping in xml is done.

//@WebServlet("/FirstServ")
//@WebServlet("/SecondServ")

An old thread, but since I didn't find it elsewhere, here is one more possibility:

If you're using servlet-api 3.0+, then your web.xml must NOT include metadata-complete="true" attribute

enter image description here

This tells tomcat to map the servlets using data given in web.xml instead of using the @WebServlet annotation.


Solution for HTTP Status 404 in NetBeans IDE: Right click on your project and go to your project properties, then click on run, then input your project relative URL like index.jsp.

  1. Project->Properties
  2. Click on Run
  3. Relative URL:/index.jsp (Select your project root URL)

enter image description here


I removed the old web library such that are spring framework libraries. And build a new path of the libraries. Then it works.


My issue was that my method was missing the @RequestBody annotation. After adding the annotation I no longer received the 404 exception.


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 newer
  • javax.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 server itself. This way you eliminiate potential environment-specific problems. Packageless servlets work only in specific Tomcat+JDK combinations and this should never be relied upon.

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. Below is an example of the folder structure of a default Eclipse Dynamic Web Project as seen in Navigator view:

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!

@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?

@WebServlet works only on Servlet 3.0 or newer

In order to use @WebServlet, you only 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. Below is a Servlet 4.0 compatible one (which matches Tomcat 9+, WildFly 11+, 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.

package com.example;

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>
</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.http.*;

to

import jakarta.servlet.*;
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: Tomcat 9 casting servlets to javax.servlet.Servlet instead of jakarta.servlet.http.HttpServlet

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 javax.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 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, 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>. 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 you need to submit to a servlet located in http://localhost:8080/contextname/servlet, here are several cases (note that you can safely substitute <form action> with <a href> here):

  • 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.


  • 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:

Other cases of HTTP Status 404 error:


I was facing this issue too, I was receiving a 404 when accessing a URL pattern that I knew was linked to a Servlet. The reason is because I had 2 Servlets with their @WebServlet name parameter set as the same string.

@WebServlet(name = "ServletName", urlPatterns = {"/path"})
public class ServletName extends HttpServlet {}
@WebServlet(name = "ServletName", urlPatterns = {"/other-path"})
public class OtherServletName extends HttpServlet {}

Both of the name parameters are the same. If you're using the name parameter, make sure they are unique compared to all other Servlets on your application.


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to forms

How do I hide the PHP explode delimiter from submitted form results? React - clearing an input value after form submit How to prevent page from reloading after form submit - JQuery Input type number "only numeric value" validation Redirecting to a page after submitting form in HTML Clearing input in vuejs form Cleanest way to reset forms Reactjs - Form input validation No value accessor for form control TypeScript-'s Angular Framework Error - "There is no directive with exportAs set to ngForm"

Examples related to jsp

Difference between request.getSession() and request.getSession(true) A child container failed during start java.util.concurrent.ExecutionException The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path Using if-else in JSP Passing parameters from jsp to Spring Controller method how to fix Cannot call sendRedirect() after the response has been committed? How to include js and CSS in JSP with spring MVC How to create an alert message in jsp page after submit process is complete getting error HTTP Status 405 - HTTP method GET is not supported by this URL but not used `get` ever? How to pass the values from one jsp page to another jsp without submit button?

Examples related to servlets

Google Recaptcha v3 example demo Difference between request.getSession() and request.getSession(true) init-param and context-param java.lang.NoClassDefFoundError: org/json/JSONObject how to fix Cannot call sendRedirect() after the response has been committed? getting error HTTP Status 405 - HTTP method GET is not supported by this URL but not used `get` ever? Create a simple Login page using eclipse and mysql Spring get current ApplicationContext insert data into database using servlet and jsp in eclipse What is WEB-INF used for in a Java EE web application?

Examples related to http-status-code-404

Tomcat 404 error: The origin server did not find a current representation for the target resource or is not willing to disclose that one exists Vue-router redirect on page not found (404) Apache: The requested URL / was not found on this server. Apache Tomcat Servlet: Error 404 - The requested resource is not available Django, creating a custom 500/404 error page TOMCAT - HTTP Status 404 Object not found! The requested URL was not found on this server. localhost Getting 404 Not Found error while trying to use ErrorDocument Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available" MIME types missing in IIS 7 for ASP.NET - 404.17