Вопрос

How can I retrieve the HTTP POST request body when implementing NanoHTTPDs serve method?

I've tried to use the getInputStream() method of IHTTPSession already, but I always get an SocketTimeoutException when using it inside of the serve method.

Это было полезно?

Решение

In the serve method you first have to call session.parseBody(files), where files is a Map<String, String>, and then session.getQueryParameterString() will return the POST request's body.

I found an example in the source code. Here is the relevant code:

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.
}

Другие советы

On a IHTTPSession instance you can call the .parseBody(Map<String, String>) method which will then fill the map you provided with some values.

Afterwards your map may contain a value under the key postBody.

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

This value will then hold your posts body.

Code that does this, can be found here.

I think session.getQueryParameterString(); not work in this case.

If you using POST, PUT, you should want to try this code:

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));

In fact, I tried IOUtils.toString(inputstream, encoding) but it cause Timeout exception!

This is how I am getting my post response body with NanoHttp, and it works for me. Very important to note that if you are handling your own error response codes and want to send a body use the error input stream instead of the conn.getInputStream() This will avoid the file not found exception or broken pipe exception if close the connection before the server sent the body.

 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);

I've used this method and worked for me without socket exception.

String body = "";

try {
    Map<String, String> headers = session.getHeaders();
    if (headers == null || headers.get("content-length") == null) {
        iDoMethodInThread.onException(new Exception("No Content length found in header"));
        return;
    }
    int contentLength = Integer.parseInt(headers.get("content-length"));
    byte[] buffer = new byte[contentLength];
    int totalRead = 0;
    while (totalRead < contentLength) {
        int read = session.getInputStream().read(buffer, totalRead, contentLength - totalRead);
        if (read == -1) {
            break;
        }
        totalRead += read;
    }
    body = new String(buffer, StandardCharsets.UTF_8);
} catch (IOException e) {
    e.printStackTrace();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top