Ponga la clase de servlet en un package
En primer lugar, coloque la clase de servlet en Java package
. Usted debe siempre poner clases reutilizables públicamente Java en un paquete, si no que son invisibles a las clases que se encuentran en un paquete, como el propio servidor. De esta forma, elimina posibles problemas específicos del entorno. Los servlets sin paquete funcionan solo en combinaciones específicas de Tomcat + JDK y nunca se debe confiar en esto.
En el caso de un proyecto IDE "simple", la clase debe colocarse en su estructura de paquete dentro de la carpeta "Recursos Java" y, por lo tanto, no en "WebContent", esto es para archivos web como JSP. A continuación se muestra un ejemplo de la estructura de carpetas de un proyecto web dinámico de Eclipse predeterminado como se ve en la vista del navegador :
EclipseProjectName
|-- src
| `-- com
| `-- example
| `-- YourServlet.java
|-- WebContent
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
En el caso de un proyecto Maven, la clase debe colocarse en su estructura de paquete dentro main/java
y, por lo tanto, nomain/resources
, por ejemplo , esto es para archivos que no son de clase . A continuación se muestra un ejemplo de la estructura de carpetas de un proyecto de aplicación web Maven predeterminado como se ve en la vista del navegador de Eclipse :
MavenProjectName
|-- src
| `-- main
| |-- java
| | `-- com
| | `-- example
| | `-- YourServlet.java
| |-- resources
| `-- webapp
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
Tenga en cuenta que la /jsps
subcarpeta no es estrictamente necesaria. Incluso puede prescindir de él y poner el archivo JSP directamente en la raíz webcontent / webapp, pero solo me estoy haciendo cargo de esto de su pregunta.
Establecer URL de servlet en url-pattern
La URL del servlet se especifica como el "patrón de URL" del mapeo del servlet. No es en absoluto, por definición, el nombre de clase / nombre de archivo de la clase de servlet. El patrón de URL se especificará como valor de @WebServlet
anotación.
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.
// ...
}
En caso de que desee admitir parámetros de ruta como /servlet/foo/bar
, utilice un patrón de URL de /servlet/*
. Vea también Servlet y parámetros de ruta como / xyz / {value} / test, ¿cómo mapear en web.xml?
@WebServlet
funciona solo en Servlet 3.0 o más reciente
Para usarlo @WebServlet
, solo necesita asegurarse de que su web.xml
archivo, si lo hay (es opcional desde Servlet 3.0), se declara conforme con la versión Servlet 3.0+ y, por lo tanto, no es conforme, por ejemplo, la versión 2.5 o inferior . A continuación se muestra uno compatible con Servlet 4.0 (que coincide con Tomcat 9+, WildFly 11+, Payara 5+, etc.).
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
>
<!-- Config here. -->
</web-app>
O, en caso de que aún no esté en Servlet 3.0+ (por ejemplo, Tomcat 6 o anterior), elimine la @WebServlet
anotación.
package com.example;
public class YourServlet extends HttpServlet {
// ...
}
Y registre el servlet en su lugar web.xml
así:
<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>
Por lo tanto, tenga en cuenta que no debe utilizar ambas formas. Utilice una configuración basada en anotaciones o una configuración basada en XML. Cuando tenga ambos, la configuración basada en XML anulará la configuración basada en anotaciones.
Verificando la construcción / implementación
En caso de que esté utilizando una herramienta de compilación como Eclipse y / o Maven, debe asegurarse absolutamente de que el archivo de clase de servlet compilado resida en su estructura de paquete en la /WEB-INF/classes
carpeta del archivo WAR producido. En caso de package com.example; public class YourServlet
, debe estar ubicado en /WEB-INF/classes/com/example/YourServlet.class
. De lo contrario, se enfrentará también en caso de @WebServlet
un error 404, o en caso de <servlet>
un error HTTP 500 como el siguiente:
Estado HTTP 500
Error al crear una instancia de la clase de servlet com.example.YourServlet
Y busque en el registro del servidor a java.lang.ClassNotFoundException: com.example.YourServlet
, seguido de a java.lang.NoClassDefFoundError: com.example.YourServlet
, seguido de javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
.
Una manera fácil de verificar si el servlet está correctamente compilado y colocado en classpath es dejar que la herramienta de compilación produzca un archivo WAR (por ejemplo, haga clic con el botón derecho en el proyecto, Exportar> Archivo WAR en Eclipse) y luego inspeccione su contenido con una herramienta ZIP. Si falta la clase de servlet /WEB-INF/classes
, o si la exportación causa un error, entonces el proyecto está mal configurado o algunos valores predeterminados de configuración de IDE / proyecto se han revertido por error (por ejemplo, Proyecto> Construir automáticamente se ha deshabilitado en Eclipse).
También debe asegurarse de que el icono del proyecto no tenga una cruz roja que indique un error de compilación. Puede encontrar el error exacto en la vista Problemas ( Ventana> Mostrar vista> Otro ... ). Por lo general, el mensaje de error se puede buscar en Google. En caso de que no tenga ni idea, lo mejor es reiniciar desde cero y no tocar ningún IDE / configuración predeterminada del proyecto. En caso de que esté utilizando Eclipse, puede encontrar instrucciones en ¿Cómo importo la API javax.servlet en mi proyecto Eclipse?
Probando el servlet individualmente
Siempre que el servidor se ejecute localhost:8080
y que el WAR se implemente con éxito en una ruta de contexto de /contextname
(que por defecto es el nombre del proyecto IDE, distingue entre mayúsculas y minúsculas), y el servlet no ha fallado en su inicialización (lea los registros del servidor para cualquier implementación / mensajes de éxito / error del servlet y la ruta de contexto real y el mapeo del servlet), entonces hay un servlet con el patrón de URL /servlet
disponible en http://localhost:8080/contextname/servlet
.
Puede ingresarlo directamente en la barra de direcciones del navegador para probarlo de forma individual. Si doGet()
se reemplaza e implementa correctamente, verá su salida en el navegador. O si no tiene ninguno doGet()
o si llama incorrectamente super.doGet()
, se mostrará un error " HTTP 405: el método HTTP GET no es compatible con esta URL " (que es mejor que un 404, ya que un 405 es evidencia de que el servlet sí mismo se encuentra realmente).
Anular service()
es una mala práctica, a menos que esté reinventando un marco MVC, lo cual es muy poco probable si recién está comenzando con servlets y no tiene ni idea del problema descrito en la pregunta actual;) Consulte también Diseñar patrones de aplicaciones basadas en web .
Independientemente, si el servlet ya devuelve 404 cuando se prueba de forma individual, entonces no tiene sentido intentarlo con un formulario HTML. Lógicamente, por lo tanto, tampoco tiene sentido incluir ningún formulario HTML en preguntas sobre errores 404 de un servlet.
Hacer referencia a la URL del servlet desde HTML
Una vez que haya verificado que el servlet funciona bien cuando se invoca individualmente, puede avanzar a HTML. En cuanto a su problema concreto con el formulario HTML, el <form action>
valor debe ser una URL válida. Lo mismo se aplica a <a href>
. Debe comprender cómo funcionan las URL absolutas / relativas. Ya sabes, una URL es una dirección web que puedes ingresar / ver en la barra de direcciones del navegador web. Si especifica una URL relativa como acción de formulario, es decir, sin el http://
esquema, entonces se vuelve relativa a la URL actual como ve en la barra de direcciones de su navegador web. Por lo tanto, no es en absoluto relativo a la ubicación del archivo JSP / HTML en la estructura de carpetas WAR del servidor, como parecen pensar muchos principiantes.
Entonces, asumiendo que la página JSP con el formulario HTML es abierta por http://localhost:8080/contextname/jsps/page.jsp
, y necesita enviarla a un servlet ubicado en http://localhost:8080/contextname/servlet
, aquí hay varios casos (tenga en cuenta que puede sustituir <form action>
con seguridad <a href>
aquí):
La acción del formulario se envía a una URL con una barra inclinada.
<form action="/servlet">
La barra inclinada /
hace que la URL sea relativa al dominio, por lo que el formulario se enviará a
http://localhost:8080/servlet
Pero esto probablemente resultará en un 404 ya que está en el contexto incorrecto.
La acción de formulario se envía a una URL sin una barra inclinada.
<form action="servlet">
Esto hace que la URL sea relativa a la carpeta actual de la URL actual, por lo que el formulario se enviará a
http://localhost:8080/contextname/jsps/servlet
Pero esto probablemente resultará en un 404 ya que está en la carpeta incorrecta.
La acción del formulario se envía a una URL que sube una carpeta.
<form action="../servlet">
Esto subirá una carpeta (¡exactamente como en las rutas del sistema de archivos del disco local!), Por lo que el formulario se enviará a
http://localhost:8080/contextname/servlet
¡Este debe funcionar!
El enfoque canónico, sin embargo, es hacer que la URL sea relativa al dominio para que no necesite corregir las URL una vez más cuando mueva los archivos JSP a otra carpeta.
<form action="${pageContext.request.contextPath}/servlet">
Esto generará
<form action="/contextname/servlet">
Por lo tanto, siempre se enviará a la URL correcta.
Utilice comillas rectas en HTML
Debe asegurarse absolutamente de que está utilizando comillas rectas en atributos HTML como action="..."
o action='...'
y, por lo tanto, no comillas como action=”...”
o action=’...’
. Las comillas curvas no son compatibles con HTML y simplemente se convertirán en parte del valor.
Ver también:
Otros casos de error HTTP Status 404:
Escenario # 1: Usted accidentalmente volver a desplegarse desde la línea de comandos, mientras que Tomcat se está ejecutando .
Respuesta corta: Detenga Tomcat, elimine la carpeta de destino , el paquete mvn y luego vuelva a implementar
Escenario n. ° 2: request.getRequestDispatcher (" MIS_SPELLED_FILE_NAME .jsp ")
Respuesta corta: Verifique la ortografía del nombre del archivo , asegúrese de que el caso sea correcto.
Escenario n. ° 3: Excepciones de clase no encontrada (la respuesta se puso aquí porque: Pregunta n. ° 17982240) ( java.lang.ClassNotFoundException para servlet en tomcat con eclipse ) (se marcó como duplicado y me dirigió aquí)
Respuesta corta # 3.1: web.xml tiene una ruta de paquete incorrecta en la etiqueta de clase de servlet.
Respuesta corta # 3.2: el archivo java tiene una declaración de importación incorrecta.
A continuación se muestran más detalles para el escenario n. ° 1:
1: Detén a Tomcat
2: Elimina la carpeta "destino". (mvn clean no te ayudará aquí)
3: paquete mvn
4: YOUR_DEPLOYMENT_COMMAND_HERE
(Mío: java -jar target / dependency / webapp-runner.jar --port 5190 target / *. War)
Historia completa:
Abrí accidentalmente una nueva ventana de git-bash e intenté implementar un archivo .war para mi proyecto heroku a través de:
java -jar target / dependency / webapp-runner.jar --port 5190 target / *. war
Después de una falla en la implementación, me di cuenta de que tenía dos ventanas git-bash abiertas y no había usado CTLR + C para detener la implementación anterior .
Me encontré con:
A continuación se muestran más detalles para el escenario n. ° 3:
ESCENARIO 3.1: La ruta del paquete de clase servlet es incorrecta en su archivo web.xml.
Debe COINCIDIR con la declaración del paquete en la parte superior de su clase de servlet java.
Archivo: my_stuff / MyClass.java :
Archivo: PRJ_ROOT / src / main / webapp / WEB-INF / web.xml
ESCENARIO 3.2:
Pones la declaración " paquete " incorrecta en la parte superior de tu archivo myClass.java.
Por ejemplo:
El archivo está en: carpeta " / my_stuff "
Escribes por error:
Esto es complicado porque:
1: La compilación de maven (paquete mvn) no informará ningún error aquí.
2: la línea de clase de servlet en web.xml puede tener la ruta CORRECTA del paquete. P.ej:
Pila utilizada: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :
fuente
Solución para
HTTP Status 404
en NetBeans IDE: Haga clic derecho en su proyecto y vaya a las propiedades de su proyecto, luego haga clic en ejecutar, luego ingrese la URL relativa de su proyecto comoindex.jsp
.fuente
Mi problema fue que a mi método le faltaba la anotación @RequestBody. Después de agregar la anotación, ya no recibí la excepción 404.
fuente
Realice los siguientes dos pasos. Espero que resuelva el problema "404 no encontrado" en el servidor tomcat durante el desarrollo de la aplicación de servlet Java.
Paso 1:
Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server
Paso 2:
Double Click on the server(in the server explorer tab)->Select Use tomcat installation option inside server location menu
fuente
Eliminé la antigua biblioteca web, que son bibliotecas de marco de primavera. Y construye un nuevo camino de las bibliotecas. Entonces funciona.
fuente
Un hilo antiguo, pero como no lo encontré en otro lugar, aquí hay una posibilidad más:
Si está utilizando servlet-api 3.0+ , entonces su web.xml NO debe incluir el
metadata-complete="true"
atributoEsto le dice a Tomcat que mapee los servlets usando los datos proporcionados en
web.xml
lugar de usar la@WebServlet
anotación.fuente
En primer lugar, ejecute su IDE como administrador. Después de eso, haga clic con el botón derecho en la carpeta del proyecto -> Facetas del proyecto y asegúrese de que la versión de Java esté configurada correctamente. En mi PC. (Por ejemplo 1.8) Ahora debería funcionar.
No inicie simplemente su servidor, por ejemplo Wildfly, usando el cmd. Debe iniciarse dentro del IDE y ahora visite la URL de su host local. Ejemplo: http: // localhost: 8080 / HelloWorldServlet / HelloWorld
fuente
La solución que funcionó para mí es (si está usando Maven): Haga clic derecho en su proyecto, Maven -> Actualizar proyecto. Esto podría darle algún otro error con el JDK y otras bibliotecas (en mi caso, el conector MySQL), pero una vez que los arregle, ¡su problema original debería solucionarse!
fuente
Si desea abrir un servlet con javascript sin usar el botón 'formulario' y 'enviar', aquí está el siguiente código:
Llave:
1) button-id: La etiqueta 'id' que le da a su botón en su archivo html / jsp.
2) ruta-servlet-completa: la ruta que se muestra en el navegador cuando ejecuta el servlet solo
fuente
El mapeo en web.xml es lo que he hecho: -
packagename.filename entre la apertura y el cierre de la etiqueta de clase de servlet en un archivo xml.
Ambos métodos no funcionan entre sí, por lo que utilizo el método de anotación de los archivos mencionados cuando creamos el servlet o la forma de mapeo, luego elimino o comento la línea de anotación. P.ej:
Comentando la línea de anotación de código en el archivo respectivo, si se realiza el mapeo en xml.
fuente
Compruebe que la raíz de contexto no puede estar vacía .
Si está utilizando eclipse:
haga clic con el botón derecho , seleccione propiedades , luego configuración del proyecto web . Compruebe que la raíz del contexto no puede estar vacía
fuente