Pregunta

Estoy intentando escribir una aplicación web usando SpringMVC. Normalmente, simplemente asignaría una extensión de archivo inventada al controlador frontal de Spring y viviría feliz, pero esta vez voy por URLs similares a REST, sin extensiones de nombre de archivo.

Mapear todo bajo mi ruta de contexto al controlador frontal (llamémosle " 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?), por lo que una combinación con el servlet predeterminado de tomcat (llamémoslo tomcat ") parece ser el camino a seguir.

Tengo la cosa 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 repitiendo este ú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?

¿Fue útil?

Solución

Creo que puedo saber lo que está pasando.

En su web.xml de trabajo, ha configurado su servlet para que sea el servlet predeterminado (/ por sí mismo es el servlet predeterminado que se llama 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 la asignación / * en web.xml, responde a todas las solicitudes, excepto a otras asignaciones de ruta. De acuerdo con 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 / contiene test.png

Intentando acceder a test.png lo intenté:

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

y no se encontró el archivo. Sin embargo intentando

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

aparece. Así que parece que el servlet predeterminado de Tomcat (al menos 6.0.16) descarta la asignación del servlet e intentará encontrar el archivo utilizando la ruta restante. De acuerdo con esta publicación, Servlet para servir contenido estático Jetty brinda el comportamiento que usted y yo esperábamos.

¿Hay alguna razón por la que no pueda hacer algo como asignar un directorio raíz para sus llamadas de descanso? Algo así como una aplicación asignada a / rest_root / * de la que eres responsable de todo lo que ocurre en la carpeta rest_root, pero Tomcat debe manejar cualquier otro lugar, a menos que hagas otra asignación explícita. Sugiero configurar su servlet de descanso en una asignación de ruta, porque declara la intención mejor. El uso de / o / * no parece apropiado, ya que tiene que mapear 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 (asignaciones de ruta)
  2. Implícito (asignaciones de extensión)
  3. Predeterminado (/)

Por favor, corrige todo lo que me equivoqué.

Otros consejos

Para 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>

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top