【问题标题】:Retrieve HTTP Body in NanoHTTPD在 NanoHTTPD 中检索 HTTP 正文
【发布时间】:2014-04-16 11:37:25
【问题描述】:

在实现NanoHTTPDs serve 方法时如何检索HTTP POST 请求正文?

我已经尝试使用IHTTPSessiongetInputStream() 方法,但是在serve 方法中使用它时总是得到SocketTimeoutException

【问题讨论】:

  • 如何使用GET方法从URL中获取参数?

标签: java nanohttpd


【解决方案1】:

serve 方法中,您首先必须调用session.parseBody(files),其中filesMap<String, String>,然后session.getQueryParameterString() 将返回POST 请求的正文。

我在源代码中找到了an example。以下是相关代码:

public Response serve(IHTTPSession session) {
    Map<String, String> files = new HashMap<String, String>();
    Method method = session.getMethod();
    if (Method.PUT.equals(method) || Method.POST.equals(method)) {
        try {
            session.parseBody(files);
        } catch (IOException ioe) {
            return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
        } catch (ResponseException re) {
            return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
        }
    }
    // get the POST body
    String postBody = session.getQueryParameterString();
    // or you can access the POST request's parameters
    String postParameter = session.getParms().get("parameter");

    return new Response(postBody); // Or postParameter.
}

【讨论】:

  • 有什么理由必须在session.getQueryParameterString() 之前调用session.parseBody(files) 吗?
  • @vatsa 我快速浏览了源代码:在处理非 multipart/form-data 请求时, session.parseBody(files) 读取 POST 请求的正文和 calls HTTPSession's decodeParms() 方法,它设置POST 正文的 queryParameterString 和 parms 字段值。如果没有调用 session.parseBody() 这些字段是空的。
【解决方案2】:

IHTTPSession 实例上,您可以调用.parseBody(Map&lt;String, String&gt;) 方法,然后该方法将用一些值填充您提供的地图。

之后,您的地图可能会在键 postBody 下包含一个值。

        final HashMap<String, String> map = new HashMap<String, String>();
        session.parseBody(map);
        final String json = map.get("postData");

该值将保存您的帖子正文。

Code that does this, can be found here.

【讨论】:

  • 迄今为止最好的解决方案,尤其是在使用 JSON 时。
  • 请注意,如果 Content-Type 为application/x-www-form-urlencoded,则参数的内容位于session.getParms() 下,而不是您提供的map 对象下
  • content-typeapplication/json 时,唯一对我有用的解决方案
  • @Rinmalavi 感谢您将链接发布到明确的代码files.put("postData", postLine); 需要使用postData 来获取数据...但是在文档中是否有任何指向此的链接形式?
  • @CrandellWS 我记得在 14 年使用它时,文档主要是代码本身。不确定事情是否发生了变化。抱歉没有回答。
【解决方案3】:

我认为session.getQueryParameterString(); 在这种情况下不起作用。

如果你使用POSTPUT,你应该想试试这个代码:

Integer contentLength = Integer.parseInt(session.getHeaders().get("content-length"));
byte[] buffer = new byte[contentLength];
session.getInputStream().read(buffer, 0, contentLength);
Log.d("RequestBody: " + new String(buffer));

事实上,我尝试了IOUtils.toString(inputstream, encoding),但它导致Timeout exception

【讨论】:

  • session.getHeaders().get("content-length") == null?
  • 当发布数据不是纯字符串格式时,这比其他的要好
【解决方案4】:

这就是我使用 NanoHttp 获取帖子响应正文的方式,它对我有用。非常重要的是要注意,如果您正在处理自己的错误响应代码并希望发送正文,请使用错误输入流而不是 conn.getInputStream() 如果之前关闭连接,这将避免找不到文件异常或损坏管道异常服务器发送了正文。

 public HashMap<String, Object> getResponse(HttpURLConnection conn) throws IOException {

        Log.i("STATUS", String.valueOf(conn.getResponseCode()));
        Log.i("MSG", conn.getResponseMessage());

        StringBuilder response = new StringBuilder();

        String line;
        BufferedReader br;

        if (conn.getResponseCode() == HttpsURLConnection.HTTP_OK)
             br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        else
            br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));

        while ((line = br.readLine()) != null)
            response.append(line);

        conn.disconnect();
        return new Gson().fromJson(response.toString(), HashMap.class);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    相关资源
    最近更新 更多