usar servlet life httpservlet example ejemplo java java-ee servlets

java - httpservlet - servlet life cycle oracle



¿Cómo se utilizan las correlaciones de URL Servlet en web.xml? (2)

Tengo un archivo web.xml con contenido:

<servlet> <servlet-name>servlet1</servlet-name> <servlet-class>org.mycompany.test1</servlet-class> </servlet> <servlet> <servlet-name>servlet2</servlet-name> <servlet-class>org.mycompany.test2</servlet-class> </servlet> <servlet-mapping> <servlet-name>servlet1</servlet-name> <url-pattern>/path/test</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>servlet2</servlet-name> <url-pattern>/path/test/*</url-pattern> </servlet-mapping>

Intenté las solicitudes

.../path/test/abc .../path/test

Ambas solicitudes son procesadas por Servlet2. ¿Por qué?

ACTUALIZAR

Gracias chicos por su ayuda. Me di cuenta de que el comportamiento depende del orden de la declaración del mapeo de servlets. Intenté este web.xml

<servlet> <servlet-name>servlet1</servlet-name> <servlet-class>org.mycompany.test1</servlet-class> </servlet> <servlet> <servlet-name>servlet2</servlet-name> <servlet-class>org.mycompany.test2</servlet-class> </servlet> <servlet> <servlet-name>servlet3</servlet-name> <servlet-class>org.mycompany.test3</servlet-class> </servlet> <servlet> <servlet-name>servlet4</servlet-name> <servlet-class>org.mycompany.test4</servlet-class> </servlet> <servlet-mapping> <servlet-name>servlet1</servlet-name> <url-pattern>/path/test</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>servlet2</servlet-name> <url-pattern>/path/test/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>servlet3</servlet-name> <url-pattern>/path/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>servlet4</servlet-name> <url-pattern>/path</url-pattern> </servlet-mapping>

resultados:

.../path/test/abc - servlet2 .../path/test/ - servlet2 .../path/test - servlet2 .../path/abc - servlet3 .../path/ - servlet4 .../path - servlet4


De la especificación de Servlet 3.0, así es como el contenedor web debe ubicar el servlet después de recibir una solicitud (énfasis mío):

La ruta utilizada para mapear a un servlet es la URL de solicitud del objeto de solicitud menos la ruta de contexto y los parámetros de ruta. Las siguientes reglas de mapeo de ruta de URL se usan en orden. La primera coincidencia exitosa se usa sin intentar más coincidencias :

  1. El contenedor intentará encontrar una coincidencia exacta de la ruta de la solicitud con la ruta del servlet. Una coincidencia exitosa selecciona el servlet.
  2. El contenedor intentará de forma recursiva hacer coincidir el prefijo de ruta más largo. Esto se hace bajando el árbol de ruta un directorio a la vez, usando el carácter ''/'' como un separador de ruta. La coincidencia más larga determina el servlet seleccionado.
  3. Si el último segmento en la ruta de la URL contiene una extensión (por ejemplo, .jsp), el contenedor de servlets intentará hacer coincidir un servlet que maneja las solicitudes para la extensión. Una extensión se define como la parte del último segmento después de la última ''.'' personaje.
  4. Si ninguna de las tres reglas anteriores da como resultado una coincidencia de servlet, el contenedor intentará mostrar el contenido apropiado para el recurso solicitado. Si se define un servlet "predeterminado" para la aplicación, se usará. Muchos contenedores proporcionan un servlet predeterminado implícito para servir contenido.

El contenedor debe usar comparaciones de cadenas sensibles a mayúsculas y minúsculas para hacer coincidir.

También debe mirar la especificación de las asignaciones (que figuran a continuación):

En el descriptor de despliegue de la aplicación web, la siguiente sintaxis se usa para definir las asignaciones:

  • Una cadena que comienza con un carácter ''/'' y termina con un sufijo ''/*'' se usa para el mapeo de ruta.

  • Una cadena que comienza con un ''*.'' el prefijo se usa como un mapeo de extensión.

  • La cadena vacía ("") es un patrón de URL especial que se correlaciona exactamente con la raíz de contexto de la aplicación, es decir, solicitudes de la forma http://host:port/<contextroot>/ . En este caso, la información de ruta es ''/'' y la ruta de acceso del servlet y el contexto es cadena vacía (““) .

  • Una cadena que contiene solo el carácter ''/'' indica el servlet "predeterminado" de la aplicación. En este caso, la ruta del servlet es el URI de solicitud menos la ruta de contexto y la información de ruta es nula.

  • Todas las otras cadenas se usan solo para coincidencias exactas

Veamos ejemplos ahora. Considere el siguiente conjunto de asignaciones:

Path Pattern Servlet /foo/bar/* servlet1 /baz/* servlet2 /catalog servlet3 *.bop servlet4

El siguiente comportamiento resultaría:

Incoming Path Servlet Handling Request /foo/bar/index.html servlet1 /foo/bar/index.bop servlet1 /baz servlet2 /baz/index.html servlet2 /catalog servlet3 /catalog/index.html “default” servlet /catalog/racecar.bop servlet4 /index.bop servlet4

Tenga en cuenta que en el caso de /catalog/index.html y /catalog/racecar.bop , el servlet mapeado a “/catalog” no se utiliza porque la coincidencia no es exacta.

Ahora viene a tu problema :)

/path/test pertenece al 5º punto de especificación de mapeos. Lo que significa que solo las rutas que terminan en /path/test se destinarán a servlet1 .

Sin embargo, /path/test/* califica para el primer punto de la misma especificación. Esto significa que:

.../path/test será manejado por servlet1 y

.../path/test/abc será manejado por servlet2

Lo cual fue verificado por mí en una aplicación de prueba.


Tus caminos entran en conflicto.

Tus dos caminos significan lo mismo, el ''/ *'' no hace ninguna diferencia. Aparentemente, cuando intenta su camino, se ejecuta la última coincidencia (servlet2).

Por lo general, pones una ruta con el nombre de Servlet, como por ejemplo:

/path/test/servlet1 /path/test/servlet2