获取JSON POST数据的HttpServletRequest方法

166

我正在使用HTTP POST方法向URL http://laptop:8080/apollo/services/rpc?cmd=execute 发送请求

同时发送POST数据。

{ "jsondata" : "data" }

HTTP请求的Content-Type为application/json; charset=UTF-8

如何从HttpServletRequest中获取POST数据(jsondata)?

如果我枚举请求参数,我只能看到一个参数,“cmd”,而不是POST数据。


7
获取请求数据的简单方法是 request.getReader().lines().collect(Collectors.joining()) - Dmitry Stolbov
2
上述提到的抛出流已关闭异常。 - Patrick
如果您使用 getReader(),流将被关闭,因为它只能被读取一次。有许多包装器实现的替代方案,允许多次调用 getReader() - Felipe Leão
你可以使用 JacksonObjectMapper 来解决这个问题,这是最简单的方法。它的重载方法 readValue 有一个变体,接受一个 Reader 和一个 Class<T>。你最终得到的是: new ObjectMapper().readValue(request.getReader(), YourBodyType.class) - 就这样了,简短而流畅。 - Ionut Ciuta
2个回答

281

通常情况下,您可以以相同的方式在servlet中获取和提交参数:

request.getParameter("cmd");

但是,仅当POST数据被编码为键值对且内容类型为"application/x-www-form-urlencoded"时,才可以这样做,就像使用标准HTML表单时一样。
如果您使用不同的编码模式来传输POST数据,例如在您发送JSON数据流时,您需要使用自定义解码器来处理原始数据流:
BufferedReader reader = request.getReader();

Json post处理示例(使用org.json包)

public void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {

  StringBuffer jb = new StringBuffer();
  String line = null;
  try {
    BufferedReader reader = request.getReader();
    while ((line = reader.readLine()) != null)
      jb.append(line);
  } catch (Exception e) { /*report an error*/ }

  try {
    JSONObject jsonObject =  HTTP.toJSONObject(jb.toString());
  } catch (JSONException e) {
    // crash and burn
    throw new IOException("Error parsing JSON request string");
  }

  // Work with the data using methods like...
  // int someInt = jsonObject.getInt("intParamName");
  // String someString = jsonObject.getString("stringParamName");
  // JSONObject nestedObj = jsonObject.getJSONObject("nestedObjName");
  // JSONArray arr = jsonObject.getJSONArray("arrayParamName");
  // etc...
}

4
看起来您只能从request.getReader中获取一次POST数据。这是真的吗?当我尝试过后,后续对请求获取post-data的调用都会失败。 - B T
12
没错,你只能读取一次请求体内容。 - Kdeveloper
5
toJSONObject方法已被移动到org.json.HTTP类中,并成为静态方法。可以使用以下代码:JSONObject jsonObject = HTTP.toJSONObject(jb.toString())来调用。 - semisided1
1
为什么我在文档中找不到fromObject(String string)方法?http://www.json.org/javadoc/org/json/JSONObject.html - XY Li
1
应该是:JSONObject jsonObject = new JSONObject(jb.toString()); - Newbie
显示剩余5条评论

-3

你是从不同的来源发布的吗(所以不同的端口或主机名)?如果是这样的话,我刚回答的这个非常新的主题可能会对你有帮助。

问题是XHR跨域策略,以及如何通过使用一种叫做JSONP的技术来绕过它的有用提示。唯一的缺点是JSONP不支持POST请求。

我知道在原帖中没有提到JavaScript,但JSON通常用于JavaScript,所以我才得出那个结论


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