Http Requests POST vs GET

2019-01-26 18:43发布

问题:

I am using a lot of HTTP Requests in an application that I am writing which uses OAuth. Currently, I am sending my GET and POST requests the same way:

HttpConnection connection = (HttpConnection) Connector.open(url
                    + connectionParameters);

            connection.setRequestMethod(method);
            connection.setRequestProperty("WWW-Authenticate",
                    "OAuth realm=api.netflix.com");

            int responseCode = connection.getResponseCode();

And this is working fine. I am successfully POSTing and GETing. However, I am worried that I am not doing POST the right way. Do I need to include in the above code the following if-statement?

if (method.equals("POST") && postData != null) {
                    connection.setRequestProperty("Content-type",
                            "application/x-www-form-urlencoded");
                    connection.setRequestProperty("Content-Length", Integer
                            .toString(postData.length));
                    OutputStream requestOutput = connection.openOutputStream();
                    requestOutput.write(postData);
                    requestOutput.close();
                }

If so, why? What's the difference? I would appreciate any feedback.

Thanks!

回答1:

connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");

The content type must match the actual format of the postData. A content type of application/x-www-form-urlencoded is only necessary if the content type is actually url encoded. E.g. you're encoding POST data as follows:

String data = "param1=" + URLEncoder.encode(param1, "UTF-8")
           + "&param2=" + URLEncoder.encode(param2, "UTF-8");

This way the other side will be able to parse the data according the specified format without breaking it.

And,

connection.setRequestProperty("Content-Length", Integer.toString(postData.length));

This is preferable to ensure a robust data transfer. If you omit this and the connection somehow get broken, then the other side will never be able to determine if the content is fully streamed in or not.

That said, the cast to HttpUrlConnection is unnecessary if you know the fact that the request method will "automatically" be set to POST if you do:

connection.setDoOutput(true);

or in your case more suitable:

connection.setDoOutput("POST".equals(method));


回答2:

From the HTML specification document:

If the processing of a form is idempotent (i.e. it has no lasting observable effect on the state of the world), then the form method should be GET. Many database searches have no visible side-effects and make ideal applications of query forms. - -

If the service associated with the processing of a form has side effects

(for example, modification of a database or subscription to a service), the method should be POST.

They are much the same just the purpose is the major difference.



回答3:

You need to set the content type header if it's required by the addressed HTTP server. There's really no way for us to know if it is or not.

The content length header should be calculated and set automatically if you don't set it explicitly, but since you know it beforehand anyway, I would set it so that your content is not unnecessarily buffered by the HttpConnection before actually sending the data.



回答4:

Use POST for requests that modify something, GET for requests that do searches or simply get documents. The difference on the browser side is that browsers avoid accidentally doing a POST request again e.g. by prompting the user for confirmation.

When processing a POST request, never respond with a document, but instead redirect the user to a GET request that contains the "form submitted" or whatever answer you want to give. This avoids problems with browser back/forward buttons because otherwise browsing to the response page would require resubmitting the POST request.