spring - Reenviar solicitudes entre contextos en Tomcat
servlets url-rewriting (2)
Me gustaría poder enviar reenvíos de solicitudes entre contextos en Tomcat con el filtro Tuckey URLRewrite. Por ejemplo, me gustaría poder enrutar una solicitud entrante con una URL amigable para SEO / usuario como http://example.com/group-elements/300245/some-descriptive-text , donde "group-elements" "no es el nombre de una aplicación desplegada, a una URL asignada a un método de controlador Java Spring para la aplicación ''foo'', como http://example.com/foo/app/group/300245/elements . Estoy usando Tomcat 7.0.27 y URLRewrite 3.2.0; Estoy trabajando con aplicaciones web Java Spring 3.1.
La documentación de URLRewrite 3.20 anota un atributo opcional de ''contexto'' para el elemento de parámetro de filtro ''a'':
If your application server is configured to allow "cross context" communication then this attribute can be used to forward (and only forward, not redirect or other "to" types) requests to a named servlet context.
On Tomcat, for instance, the application contexts in the server configuration (server.xml or context.xml) need the option crossContext="true". For instance, the two applications mentioned before ("app" and "forum") have to be defined as:
<Context docBase="app" path="/app" reloadable="true" crossContext="true"/>
<Context docBase="forum" path="/forum" reloadable="true" crossContext="true"/>
Dado eso y la discusión original sobre la característica , el atributo ''context'' parece ser lo que estoy buscando. Sin embargo, no he podido habilitar correctamente el reenvío de solicitudes entre contextos.
Aquí está mi aplicación de entrada ''Contexto'' ''foo'' en conf / server.xml:
<Context docBase="foo" path="/foo" reloadable="true" crossContext="true"/>
Tengo mi archivo urlrewrite.xml y el archivo web.xml en webapps / ROOT / WEB-INF /. Así es como se ven:
urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite>
<rule>
<from>baz</from>
<!-- Note: this ''to'' element''s value has an error. See the edit at bottom of this post for corrected version. -->
<to context="foo">/foo/app/group/300245/elements</to>
</rule>
</urlrewrite>
web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd" version="2.5">
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>logLevel</param-name>
<param-value>WARN</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
La regla definida anteriormente en urlrewrite.xml es intencionalmente básica y está codificada. En este caso, simplemente intento que el aspecto del contexto cruzado de la regla funcione antes de desarrollar las expresiones regulares en ''a'' y ''desde''.
Cuando solicito http://example.com/baz con esa regla en su lugar, Tomcat devuelve un error 404 que dice "El recurso solicitado (/ baz) no está disponible". He intentado algunas variaciones en el parámetro de filtro ''para'', pero nada ha funcionado todavía. Y no he podido encontrar ningún ejemplo de cómo se debe usar el ''contexto''.
¿Alguna idea sobre cómo podría hacer que funcione este tipo de filtro de solicitud de contexto cruzado? ¿Es posible? Me imagino que podría lograr lo que estoy tratando de cambiar el nombre de foo.war a ROOT.war o cambiar la aplicación raíz como se menciona aquí , pero me gustaría intentar hacerlo a través de URLRewrite a menos que hacerlo no sea factible o una mala idea en su cara.
Si mostrar más de mi configuración ayudaría, házmelo saber. Gracias por adelantado por cualquier contribución.
Editar :
Gracias a Christopher Schultz por la útil respuesta. En mi caso, el problema fue causado por dos cosas: 1) no tener un archivo context.xml en webapps / ROOT / META-INF, y 2) tener un error en el elemento ''to'' en la regla de reescritura de URL en webapps / ROOT / WEB-INF / urlrewrite.xml.
La solución consistía en poner un archivo context.xml adecuado en webapps / ROOT / META-INF. Como referencia para cualquier otra persona que encuentre este problema, ese archivo terminó luciendo así:
webapps / ROOT / META-INF / context.xml
<?xml version=''1.0'' encoding=''utf-8''?>
<Context docBase="ROOT" path="/" reloadable="true" crossContext="true" />
Como menciona Schultz, solo es necesario que se defina un contexto con crossContext = "true" para el contexto implicado en el elemento ''from'' en una regla de reescritura de URL dada (aquí, eso es ROOT). No es necesario definir explícitamente un contexto para la aplicación en la regla de reescritura de URL ''a''. En otras palabras, no debería necesitar crear manualmente un archivo context.xml para esa aplicación, por lo que, siguiendo el ejemplo anterior, no necesitaría definir manualmente y poner un archivo context.xml en webapps / foo / META-INF /.
La respuesta de Schultz refleja las recomendaciones para definir un contexto en la documentación oficial de Tomcat: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context .
El problema también fue causado por el hecho de que la regla de reescritura de URL en mi publicación inicial tenía un error. La versión correcta debería haber sido:
urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite>
<rule>
<from>baz</from>
<!-- Note: the use of ''/app'' instead of ''/foo/app/'' below -->
<to context="foo">/app/group/300245/elements</to>
</rule>
</urlrewrite>
Después de los comentarios que vengo hago esta posible conclusión:
Creo que estás mezclando los conceptos de un proxy inverso con contexto cruzado. El contexto cruzado es un método para compartir datos entre dos aplicaciones web dentro del mismo servidor de aplicaciones. Un proxy inverso como ''Apache http'' puede reescribir una url para pasarla a un determinado servidor detrás de ella, ocultando de manera efectiva las partes no deseadas o realizando otras operaciones como el equilibrio de carga.
La infraestructura sería: cliente -> proxy inverso -> servidor de aplicaciones
Si su webapp (real) se implementa en /foo
y desea reescribir URLs como /group-elements/baz
para reenviar ( no redirigir) a /foo/app/group/300245/elements
, entonces usted '' Tendremos que implementar su filtro de reescritura en uno de dos lugares: /group-elements
o /
.
La configuración anterior parece estar desplegándose en ROOT (que es /
) pero luego mapeando la URL /baz
a /foo/app/group/300245/elements
. En cambio, probablemente quieras esto:
<rule>
<from>/group-elements/baz</from>
<to context="foo">/foo/app/group/300245/elements</to>
</rule>
Parece que estabas intentando acceder a http://example.com/baz
que esperaba que funcionara. La última parte de la magia consistirá en hacer que el contexto ROOT
tenga un contexto cruzado (tenga en cuenta que su aplicación web NO necesita ser un contexto cruzado: solo lo hace el urlrewrite). Puede cambiar la webapp ROOT
para que sea contexto cruzado mediante addint crossContext="true"
a webapps/ROOT/META-INF/context.xml
.
Finalmente, realmente debería dejar de poner elementos de <Context>
en server.xml: dejarlos ahí básicamente significa que necesita reiniciar Tomcat para poder cambiar sus implementaciones de aplicaciones web.