Servlet returns “HTTP Status 404 The requested resource (/servlet) is not available”












68















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?










share|improve this question





























    68















    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?










    share|improve this question



























      68












      68








      68


      36






      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?










      share|improve this question
















      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?







      html forms jsp servlets http-status-code-404






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 6 '17 at 21:20









      BalusC

      845k29831383215




      845k29831383215










      asked Jul 31 '12 at 0:02









      pongaheadpongahead

      76421221




      76421221
























          4 Answers
          4






          active

          oldest

          votes


















          105














          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 e.g. main/resources, this is for non-class 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 3.1 compatible one (which matches Tomcat 8+, WildFly 8+, GlassFish 4+, etc).



          <?xml version="1.0" encoding="UTF-8"?>
          <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://xmlns.jcp.org/xml/ns/javaee"
          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
          id="WebApp_ID" version="3.1"
          >
          <!-- Config here. -->
          </web-app>


          Or, in case you're not on Servlet 3.0+ yet (not Tomcat 7 or newer, but 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.



          Verifying the build/deployment



          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, 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). In case you have no clue, best is to restart from scratch and do not touch any IDE/project configuration defaults.



          Testing the servlet individually



          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.



          Referencing the servlet URL 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



          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.



          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






          share|improve this answer


























          • web-app version="3.1" using glassfish, I could test my servlet individually just fine when I had a mapping in web.xml AND the annotation. I removed the mapping and left the annotation since I have the latest version but then I would get a 404 error ?

            – SallyRothroat
            Mar 14 '18 at 13:54











          • That can happen if you include servlet 2.5 or older libraries in the very webapp itself instead of relying on the target runtime to provide the servlet libraries by itself.

            – BalusC
            Mar 14 '18 at 14:19



















          1














          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:






          share|improve this answer


























          • Your AppName.war and thus the exploded folder name doesn't match your expected name, for example when your war file is versioned like AppName-1.0-SNAPSHOT.war and you're trying /AppName/.

            – jla
            Oct 30 '18 at 23:41



















          0














          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






          share|improve this answer

































            0














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






            share|improve this answer























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f11731377%2fservlet-returns-http-status-404-the-requested-resource-servlet-is-not-availa%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              105














              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 e.g. main/resources, this is for non-class 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 3.1 compatible one (which matches Tomcat 8+, WildFly 8+, GlassFish 4+, etc).



              <?xml version="1.0" encoding="UTF-8"?>
              <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
              id="WebApp_ID" version="3.1"
              >
              <!-- Config here. -->
              </web-app>


              Or, in case you're not on Servlet 3.0+ yet (not Tomcat 7 or newer, but 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.



              Verifying the build/deployment



              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, 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). In case you have no clue, best is to restart from scratch and do not touch any IDE/project configuration defaults.



              Testing the servlet individually



              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.



              Referencing the servlet URL 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



              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.



              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






              share|improve this answer


























              • web-app version="3.1" using glassfish, I could test my servlet individually just fine when I had a mapping in web.xml AND the annotation. I removed the mapping and left the annotation since I have the latest version but then I would get a 404 error ?

                – SallyRothroat
                Mar 14 '18 at 13:54











              • That can happen if you include servlet 2.5 or older libraries in the very webapp itself instead of relying on the target runtime to provide the servlet libraries by itself.

                – BalusC
                Mar 14 '18 at 14:19
















              105














              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 e.g. main/resources, this is for non-class 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 3.1 compatible one (which matches Tomcat 8+, WildFly 8+, GlassFish 4+, etc).



              <?xml version="1.0" encoding="UTF-8"?>
              <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
              id="WebApp_ID" version="3.1"
              >
              <!-- Config here. -->
              </web-app>


              Or, in case you're not on Servlet 3.0+ yet (not Tomcat 7 or newer, but 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.



              Verifying the build/deployment



              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, 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). In case you have no clue, best is to restart from scratch and do not touch any IDE/project configuration defaults.



              Testing the servlet individually



              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.



              Referencing the servlet URL 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



              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.



              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






              share|improve this answer


























              • web-app version="3.1" using glassfish, I could test my servlet individually just fine when I had a mapping in web.xml AND the annotation. I removed the mapping and left the annotation since I have the latest version but then I would get a 404 error ?

                – SallyRothroat
                Mar 14 '18 at 13:54











              • That can happen if you include servlet 2.5 or older libraries in the very webapp itself instead of relying on the target runtime to provide the servlet libraries by itself.

                – BalusC
                Mar 14 '18 at 14:19














              105












              105








              105







              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 e.g. main/resources, this is for non-class 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 3.1 compatible one (which matches Tomcat 8+, WildFly 8+, GlassFish 4+, etc).



              <?xml version="1.0" encoding="UTF-8"?>
              <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
              id="WebApp_ID" version="3.1"
              >
              <!-- Config here. -->
              </web-app>


              Or, in case you're not on Servlet 3.0+ yet (not Tomcat 7 or newer, but 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.



              Verifying the build/deployment



              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, 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). In case you have no clue, best is to restart from scratch and do not touch any IDE/project configuration defaults.



              Testing the servlet individually



              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.



              Referencing the servlet URL 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



              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.



              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






              share|improve this answer















              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 e.g. main/resources, this is for non-class 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 3.1 compatible one (which matches Tomcat 8+, WildFly 8+, GlassFish 4+, etc).



              <?xml version="1.0" encoding="UTF-8"?>
              <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
              id="WebApp_ID" version="3.1"
              >
              <!-- Config here. -->
              </web-app>


              Or, in case you're not on Servlet 3.0+ yet (not Tomcat 7 or newer, but 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.



              Verifying the build/deployment



              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, 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). In case you have no clue, best is to restart from scratch and do not touch any IDE/project configuration defaults.



              Testing the servlet individually



              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.



              Referencing the servlet URL 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



              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.



              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







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 13 '17 at 6:47

























              answered Jul 31 '12 at 0:24









              BalusCBalusC

              845k29831383215




              845k29831383215













              • web-app version="3.1" using glassfish, I could test my servlet individually just fine when I had a mapping in web.xml AND the annotation. I removed the mapping and left the annotation since I have the latest version but then I would get a 404 error ?

                – SallyRothroat
                Mar 14 '18 at 13:54











              • That can happen if you include servlet 2.5 or older libraries in the very webapp itself instead of relying on the target runtime to provide the servlet libraries by itself.

                – BalusC
                Mar 14 '18 at 14:19



















              • web-app version="3.1" using glassfish, I could test my servlet individually just fine when I had a mapping in web.xml AND the annotation. I removed the mapping and left the annotation since I have the latest version but then I would get a 404 error ?

                – SallyRothroat
                Mar 14 '18 at 13:54











              • That can happen if you include servlet 2.5 or older libraries in the very webapp itself instead of relying on the target runtime to provide the servlet libraries by itself.

                – BalusC
                Mar 14 '18 at 14:19

















              web-app version="3.1" using glassfish, I could test my servlet individually just fine when I had a mapping in web.xml AND the annotation. I removed the mapping and left the annotation since I have the latest version but then I would get a 404 error ?

              – SallyRothroat
              Mar 14 '18 at 13:54





              web-app version="3.1" using glassfish, I could test my servlet individually just fine when I had a mapping in web.xml AND the annotation. I removed the mapping and left the annotation since I have the latest version but then I would get a 404 error ?

              – SallyRothroat
              Mar 14 '18 at 13:54













              That can happen if you include servlet 2.5 or older libraries in the very webapp itself instead of relying on the target runtime to provide the servlet libraries by itself.

              – BalusC
              Mar 14 '18 at 14:19





              That can happen if you include servlet 2.5 or older libraries in the very webapp itself instead of relying on the target runtime to provide the servlet libraries by itself.

              – BalusC
              Mar 14 '18 at 14:19













              1














              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:






              share|improve this answer


























              • Your AppName.war and thus the exploded folder name doesn't match your expected name, for example when your war file is versioned like AppName-1.0-SNAPSHOT.war and you're trying /AppName/.

                – jla
                Oct 30 '18 at 23:41
















              1














              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:






              share|improve this answer


























              • Your AppName.war and thus the exploded folder name doesn't match your expected name, for example when your war file is versioned like AppName-1.0-SNAPSHOT.war and you're trying /AppName/.

                – jla
                Oct 30 '18 at 23:41














              1












              1








              1







              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:






              share|improve this answer















              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:







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jul 27 '18 at 0:26

























              answered Jul 16 '18 at 6:09









              J.M.I. MADISONJ.M.I. MADISON

              1,072108




              1,072108













              • Your AppName.war and thus the exploded folder name doesn't match your expected name, for example when your war file is versioned like AppName-1.0-SNAPSHOT.war and you're trying /AppName/.

                – jla
                Oct 30 '18 at 23:41



















              • Your AppName.war and thus the exploded folder name doesn't match your expected name, for example when your war file is versioned like AppName-1.0-SNAPSHOT.war and you're trying /AppName/.

                – jla
                Oct 30 '18 at 23:41

















              Your AppName.war and thus the exploded folder name doesn't match your expected name, for example when your war file is versioned like AppName-1.0-SNAPSHOT.war and you're trying /AppName/.

              – jla
              Oct 30 '18 at 23:41





              Your AppName.war and thus the exploded folder name doesn't match your expected name, for example when your war file is versioned like AppName-1.0-SNAPSHOT.war and you're trying /AppName/.

              – jla
              Oct 30 '18 at 23:41











              0














              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






              share|improve this answer






























                0














                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






                share|improve this answer




























                  0












                  0








                  0







                  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






                  share|improve this answer















                  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







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jun 25 '18 at 11:43









                  Armali

                  7,120936100




                  7,120936100










                  answered Jun 25 '18 at 11:27









                  O R ImonO R Imon

                  11




                  11























                      0














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






                      share|improve this answer




























                        0














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






                        share|improve this answer


























                          0












                          0








                          0







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






                          share|improve this answer













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







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jan 4 at 17:24









                          THE_DOMTHE_DOM

                          3,32111217




                          3,32111217






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f11731377%2fservlet-returns-http-status-404-the-requested-resource-servlet-is-not-availa%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                              ComboBox Display Member on multiple fields

                              Is it possible to collect Nectar points via Trainline?