HttpServletRequest getParameter AND getReader

3
我正在开发一个处理POST请求的HttpServlet,该请求包括查询字符串中的参数和JSON对象。它不是表单提交,整个主体都是JSON对象。我知道需要使用HttpServletRequest.getReader()来读取主体。但我也需要使用HttpServletRequest.getParameter()来获取查询参数。而且我知道两者都不能同时使用。
我认为预期的解决方案是创建一个HttpServletRequestWrapper,并以允许多次调用的方式重写getReader()。但我无法弄清楚如何做到这一点。或者也许这不是预期的方法。我能找到的所有HttpServletRequestWrapper示例似乎都与创建过滤器和修改请求内容有关。
非常感谢任何帮助。
顺便说一下,这是托管在Google App Engine上的,但我认为这不会影响解决方案。

1
“我知道有人认为两者不能同时使用”...但事实并非如此。你可以毫无问题地同时使用它们。 - skaffman
5
@skaffman:这不是真的。请阅读getParameter()的Javadoc的最后一段,http://download.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getParameter%28java.lang.String%29 POST参数作为请求体发送。因此,如果它们尚未被解析并且您读取了正文,则将无法使用getParameter(),反之亦然。 - BalusC
@BalusC:OP说参数在查询字符串中,而不是在正文中(即它们没有被表单编码)。即使使用POST也是允许的。 - skaffman
1
当我说两者都不能使用时,我的意思是getReader()和getParameter()方法都不能使用。应用程序中的POST确实会在查询字符串中发送一些信息和主要信息在正文中。我将尝试使用getParameterMap()。 - dakamojo
1
所以我尝试使用 getParameterMap(),然后迭代键,我注意到有一个键包含整个请求体。该映射中的条目没有值。这有点奇怪,因为我需要的是键。但这似乎不是正确的方法。 - dakamojo
显示剩余2条评论
2个回答

1

我认为您可以在HttpServletRequestWrapper中实现多可调用的getReader()

  1. 将HTTP请求正文保存到临时文件中。
  2. 当调用HttpServletRequestWrapper.getReader()时,打开临时文件。
  3. 在请求处理结束时删除临时文件。

要实现(1)和(3),ServletFilter可能很有用。


2
为了保存请求体,我需要在底层的HttpServletRequest上调用getReader(),对吗?这意味着所有对getParameters()等方法的调用都将失败。我是否需要自己解析所有参数和头信息? - dakamojo

1
我建议通过解析查询字符串直接读取查询字符串参数。这样你就不会触及到消息体,并且可以使用HttpServletRequest.getReader()
解析查询字符串很棘手,但使用Apache Http Client包中的URLEncodedUtils可以安全地完成,如此处所讨论的:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接