java tomcat servlets post tomcat5.5

java - Lea el cuerpo POST de HTTPServletRequest Y luego llame a getParameter en Tomcat



servlets tomcat5.5 (2)

Estoy en la situación en que mi aplicación necesita inspeccionar el contenido / datos / cuerpo / carga de una solicitud POST sin cambiar los resultados de las siguientes llamadas a getParameter.

Leyendo el cuerpo desde InputStream:

El cuerpo se puede leer utilizando InputStream desde request.getInputStream o BufferedReader desde request.getReader .

Lectura de los parámetros POST:

Las solicitudes POST suelen incluir parámetros de solicitud en el cuerpo de la solicitud. Estos se pueden recuperar usando getParameter .

El problema:

la primera llamada getParameter analiza internamente el inputStream e inserta todos los parámetros en un parámetro HashMap. Requiere que inputStream aún contenga los contenidos para el análisis. Por lo tanto, uno no puede inspeccionar el contenido y aún tener una llamada getParameter en funcionamiento.

Propuesta (pero no suficiente) Solución

Cree un contenedor de solicitudes que almacena en caché el inputstream y devuelve el caché para getInputStream.

He visto esa solución sugerida en toda la web, pero no funciona, porque getParameter realidad no llama a getInputStream , sino que se refiere al inputBuffer original enterrado en el objeto de solicitud. Lo he intentado, tanto desde dentro del Servlet como mediante el uso de un filtro

La única solución en la que puedo pensar involucra reescribir getParameter para realmente analizar la escala de entrada en caché manualmente. Pero esto parece una mala idea.

¿Alguien tiene alguna alternativa que funcione? (Este es Tomcat 5.5) Parece que debería ser un caso de uso común; No puedo creer lo difícil que es.


(Ese es un gato viejo, estoy asumiendo que actualizarlo a uno más moderno no es una opción).

Lo que quiere hacer será interceptar la construcción del objeto concreto HttpServletResponse envolviendo el InputStream subyacente. Envolver ese InputStream en un flujo de entrada push-back (o equivalente) es necesario.

Tomcat 5.5 es tan viejo que ni siquiera puedo pensar cómo se lograría ''normalmente'', pero tal vez podría escribir un filtro que use la reflexión para alcanzar y cambiar el objeto InputStream dentro del objeto concreto de solicitud.


Como lo sugiere @caskey, una posible solución sería usar la reflexión para reemplazar el InputBuffer con un buffer de entrada reutilizable. Pero no usé ese enfoque porque se sentía travieso.

En su lugar, creé un contenedor de solicitudes en un filtro que lee el flujo de entrada en una matriz de bytes y devuelve un nuevo InputStream que internamente usa un ByteArrayInputStream alrededor de ese conjunto para todas getInputStream llamadas a getInputStream .

Después de leer el flujo de entrada a la matriz de bytes, creo un mapa de parámetros mediante el análisis de la carga útil. Combiné el mapa de parámetros de la superclase para admitir casos GET con parámetros de consulta. He reemplazado todos los métodos getParameter * () para usar este mapa de parámetros.

Utilicé apache.axis.utils.IOUtils.readFully para leer fácilmente la secuencia en la matriz de bytes. Y actualmente estoy usando javax.servlet.http.HttpUtils.parsePostData para analizar los datos en el mapa de parámetros. HttpUtils.parsePostData está en desuso, por lo que probablemente lo reemplace con una versión mejor cuando lo encuentre.

Pero esto funciona, ¡oye!