3

I am developing a HttpServlet that handles a POST request from an application that includes parameters on the query string, and a JSON object in the body. It is not a form post, the entire body is the JSON object. I understand that I need to use HttpServletRequest.getReader() to read the body. But I also need to use HttpServletRequest.getParameter() to get the query parameters. And I understand that both can not be used.

I think the intended solution is to create a HttpServletRequestWrapper and override getReader() in such a way as to allow it to be called more than once. But I can't figure out how to do that. Or maybe this is not the intended approach. All the examples of HttpServletRequestWrapper that I can find seem to be related to creating filters and modifying the contents of the request.

Any help is greatly appreciated.

BTW, this is hosted on Google App Engine, but I don't think that will affect the solution.

skaffman
  • 398,947
  • 96
  • 818
  • 769
dakamojo
  • 1,839
  • 5
  • 21
  • 35
  • 1
    "And I understand that both can not be used"... this is not true. You can use both without a problem. – skaffman May 03 '11 at 15:54
  • 5
    @skaffman: this is not true. Read the last paragraph of `getParameter()` javadoc http://download.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getParameter%28java.lang.String%29 POST parameters are sent as request body. So if they are not parsed yet and you read the body, then you won't be able to use `getParameter()` and vice versa. – BalusC May 03 '11 at 16:15
  • @BalusC: The OP says the parameters are in the query string, not the body (i.e. they're not form-encoded). This is allowed even with a POST. – skaffman May 03 '11 at 16:31
  • @skaffman: Ah right. That does then not explain why the OP posted this question. @Darrell: Did you try it yourself anyway? What happens instead? How about `request.getQueryString()`? – BalusC May 03 '11 at 16:36
  • Note that the other getParameter***(..) methods don't have the same warning as getParameter(String). It might be worth checking out if they are in fact safer. – Ladlestein May 03 '11 at 17:57
  • 1
    When I say both can not be used, I mean both methods getReader() and getParameter() can not be used. The POST from the app does indeed send some infor in the querystring and the main info in the body. I will try getParameterMap(). – dakamojo May 03 '11 at 18:41
  • 1
    So I tried getParameterMap() and then iterate over the keys and I noticed that there is one key that has the entire body of the request in it. That entry in the map has no value. So its a little weird because the key is what I want. But this doesn't seem like the right way to do this. – dakamojo May 03 '11 at 18:59

2 Answers2

1

I think you can implement multiple-callable getReader() in your HttpServletRequestWrapper :

  1. save the HTTP-request body into a temporary file.
  2. when HttpServletRequestWrapper.getReader() is called, open the temporary file.
  3. delete the temporary file at the end of request processing.

to implement (1) and (3), ServletFilter may be useful.

skaffman
  • 398,947
  • 96
  • 818
  • 769
t_motooka
  • 555
  • 5
  • 12
  • 2
    In order to save the body, I would have to call getReader() on the underlying HttpServletRequest, correct? Which means that all calls to things like getParameters() will now fail. Do I have to parse all the parameters and headers and everything myself? – dakamojo May 03 '11 at 18:28
1

I would suggest reading the query string parameters directly by parsing the query string. This way you won't touch the message body and you can use HttpServletRequest.getReader().

Parsing the query string is tricky but there it can be done safely using URLEncodedUtils from Apache Http Client package as discussed here:

Community
  • 1
  • 1
Dan
  • 2,157
  • 21
  • 15