sirve servlet que para example ejemplo contenedor java java-ee servlets spring-mvc web.xml

que - servlet java ejemplo



¿Alguien puede explicar el mapeo de servlets? (3)

Intento escribir una aplicación web usando SpringMVC. Normalmente me gustaría asignar una extensión de archivo inventado al controlador frontal de Spring y vivir feliz, pero esta vez voy a buscar URL similares a REST, sin extensiones de nombre de archivo.

Mapear todo en mi ruta de contexto al controlador frontal (llamémoslo " aplicación ") significa que también debería ocuparme de los archivos estáticos, algo que preferiría no hacer (¿por qué reinventar otro weel?), Así que alguna combinación con el valor predeterminado de tomcat servlet (llamémoslo " tomcat ") parece ser el camino a seguir.

Lo tengo para trabajar haciendo algo como

<servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>tomcat</servlet-name> <url-pattern>*.ext</url-pattern> </servlet-mapping>

y repetir el último para cada una de las extensiones de archivo de mi contenido estático. Me pregunto por qué las siguientes configuraciones, que para mí son equivalentes a la anterior, no funcionan.

<!-- failed attempt #1 --> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>tomcat</servlet-name> <url-pattern>*.ext</url-pattern> </servlet-mapping> <!-- failed attempt #2 --> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>tomcat</servlet-name> <url-pattern>/some-static-content-folder/*</url-pattern> </servlet-mapping>

¿Alguien puede arrojar algo de luz?


Como referencia, el "intento fallido # 2" es perfectamente correcto en la versión de Tomcat> = a 6.0.29.

Fue el resultado de un error de Tomcat que se corrigió en la versión 6.0.29:

https://issues.apache.org/bugzilla/show_bug.cgi?id=50026

<!-- Correct for Tomcat >= 6.0.29 or other Servlet containers --> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/some-static-content-folder/*</url-pattern> </servlet-mapping>


Creo que puedo saber qué está pasando.

En su web.xml de trabajo ha configurado su servlet como el servlet predeterminado (/ por sí mismo es el servlet predeterminado llamado si no hay otras coincidencias), responderá a cualquier solicitud que no coincida con otra asignación.

En Failed 1 su mapeo / * parece ser un mapeo de ruta válido. Con el mapeo / * en web.xml responde a todas las solicitudes excepto a otras asignaciones de ruta. Según la especificación, las asignaciones de extensión son asignaciones implícitas que se sobrescriben mediante asignaciones explícitas. Es por eso que el mapeo de extensión falló. Todo se asignó explícitamente a la aplicación.

En Failed 2, la aplicación es responsable de todo, excepto del contenido que coincide con la asignación de contenido estático. Para mostrar lo que está sucediendo en la prueba rápida que configuré. Aquí hay un ejemplo. /some-static-content-folder/ contains test.png

Intentando acceder a test.png Intenté:

/some-static-content-folder/test.png

y el archivo no fue encontrado. Sin embargo, tratando

/some-static-content-folder/some-static-content-folder/test.png

aparece. Por lo tanto, parece que el servlet predeterminado de Tomcat (6.0.16 como mínimo) descarta la asignación de servlets e intentará encontrar el archivo utilizando la ruta restante. Según esta publicación Servlet para servir contenido estático, Jetty ofrece el comportamiento que tú y yo esperábamos.

¿Hay alguna razón por la que no puede hacer algo como asignar un directorio raíz para sus llamadas de descanso? Algo así como la aplicación asignada a / rest_root / * que usted es responsable de todo lo que sucede en la carpeta rest_root, pero en cualquier otro lugar debe ser manejado por Tomcat, a menos que realice otra asignación explícita. Sugiero configurar su servlet de reposo en un mapeo de ruta porque declara mejor la intención. Usar / o / * no parece apropiado, ya que tienes que trazar las excepciones. Usando SO como ejemplo, mis asignaciones de descanso serían algo así como

/ users / * para el servlet de usuario

/ posts / * para el servlet de publicaciones

Orden de mapeo

  1. Explícito (mapeos de ruta)
  2. Implícito (asignaciones de extensión)
  3. Defecto (/)

Por favor, corrija todo lo que obtuve mal.


Nunca traté de mapear un servlet como este, pero argumentaría que / * técnicamente ambos comienzan con / y terminan con / *, aunque el mismo carácter se usa para ambas coincidencias.