Pregunta

Estoy tratando de registrar el cuerpo en bruto de las solicitudes de publicación HTTP en nuestra aplicación basada en puntales, que se ejecuta en Tomcat 6. He encontrado una Publicación anterior Entonces, eso fue algo útil, pero la solución aceptada no funciona correctamente en mi caso. El problema es que quiero registrar el cuerpo de la publicación solo en ciertos casos, y Deje que los puntales analicen los parámetros del cuerpo después de registrar. Actualmente, en el filtro que escribí, puedo leer y registrar el cuerpo desde el objeto httpservletRequestwrapper, pero después de eso, los puntales no pueden encontrar ningún parámetro para analizar, por lo que la llamada de inyección de desplazamiento (que depende de uno de los parámetros de la solicitud) falla.

Cavé un poco a través del código fuente de Struts y Tomcat, y descubrí que no importa si almaceno el cuerpo posterior al cuerpo en una matriz de bytes, y expongo una transmisión y un lector basado en esa matriz; Cuando los parámetros deben analizarse, el objeto de solicitud de Tomcat accede a su interpolante interno, que ya se ha leído en ese momento.

¿Alguien tiene una idea de cómo implementar este tipo de registro correctamente?

¿Fue útil?

Solución

De hecho, Struts no analiza los parámetros, se basa en el contenedor de servlet para hacerlo. Y una vez que el contenedor ha leído el InputStream para crear el mapa de parámetros, por supuesto, no queda nada por leer. Y en la implementación de TomCat, si lee primero la entrada de InputStream, entonces la familia de métodos GetParameter* no le queda nada para funcionar, ya que, como nota correctamente, no usa GetInputStream u GetReader, sino que accede internamente a su lector optimizado. Por lo tanto, su única solución en su ServLetRequestWrapper es anular GetInputStream, GetReader y la familia GetParameter* en la que se basa los puntales para leer los parámetros. Tal vez pueda echar un vistazo a org.apache.catalina.util.requestutil para no duplicar la parte de análisis posterior al cuerpo.

Otros consejos

Lo que tiene que hacer en su filtro es leer el contenido de la publicación en su totalidad y luego, cuando vaya a pasar la solicitud a la cadena; Respalde el flujo de entrada con la suya. Por ejemplo, lee la publicación en el archivo en el disco, luego cuando llame:

chain.doFilter(new ServletRequest() {}, response);

Puede delegar la mayoría de los métodos invocaciones de su clase a la solicitud original, pero cuando llega el momento de abrir el flujo de entrada que necesita leer desde su archivo en el disco.

Debe asegurarse de no filtrar recursos, ya que esto se invocará con bastante frecuencia y puede doler si se hace incorrectamente.

El ejemplo de filtro vinculado en la pregunta se ve bien y debería funcionar. Quizás lo estés definiendo en el web.xml después El filtro de despachador de puntales. Entonces, de hecho, sería demasiado tarde para analizar y registrar el cuerpo de la solicitud y aún hacerlo disponible para puntales. Necesitas declarar este filtro antes de El filtro de despachador de puntales. El orden de filtro es importante, se invocan en el orden a medida que se definen en web.xml.

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