Original link:
https://www.jianshu.com/p/53b5bd0f1d44
In common business development, POST requests are often used in these places: when submitting front-end forms, when calling interface code, and when using Postman to test the interface. Let's understand them one by one:
1. When the front-end form is submitted
application/x-www-form-urlencoded
Form code:
<form action="http://localhost:8888/task/" method="POST"> First name: <input type="text" name="firstName" value="Mickey&"><br> Last name: <input type="text" name="lastName" value="Mouse "><br> <input type="submit" value="提交"> </form>
Through testing, it is found that the interface can be accessed normally. It can be seen in Chrome's developer tools that the form upload encoding format is application/x-www-form-urlencoded
(in Request Headers) and the parameter format is key=value&key=value
.
We can see that the server knows that the parameters are &
separated by symbols , and if required &
in the parameter value , it must be encoded. The encoding format is application/x-www-form-urlencoded
( connect the parameters of the key-value pairs with &, if there are spaces, convert the spaces to +
plus signs; with special symbols, convert the special symbols into ASCII HEX
values ).
application/x-www-form-urlencoded
Is the browser's default encoding format. For the Get request, it is the parameter conversion ?key=value&key=value
format, after connecting to the url
ps: You can test the form at this URL: http://www.runoob.com/try/try.php?filename=tryhtml_form_submit
multipart/form-data
So when the server uses to multipart/form-data
receive POST requests, how does the server know the start position and end position of each parameter?
<form action="http://localhost:8888/task/" method="POST" enctype="multipart/form-data"> First name: <input type="text" name="firstName" value="Mickey&"><br> Last name: <input type="text" name="lastName" value="Mouse "><br> <input type="submit" value="提交"> </form>
We can see in the developer tool that multipart/form-data
the parameter will not be encoded, and the value used is boundary
(divider), which is equivalent to .&
boundary
----Web**AJv3
File Upload
Upload file must also specify the encoding format multipart/form-data
.
<form action="http://localhost:8888/testFile" enctype="multipart/form-data" method="POST"> <input type="file" name="file"> <input type="submit" value="提交"> </form>
If it is a multipart/form-data
Spring MVC project, if the server can accept the type parameter, the following content must also be configured in the spring context, which is not required for the Spring Boot project .
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"></property> </bean>
We can simulate the form submission through the FormData object and send the data with the original XMLHttpRequest, so that we can view the specific format in the Chrome development tool:
<form id="form"> First name: <input type="text" name="firstName" value="Mickey"><br> Last name: <input type="text" name="lastName" value="Mouse"><br> <input type="file" name="file"><br> </form> <button onclick="submitForm()">提交</button> <script> function submitForm() { var formElement = document.getElementById("form"); var xhr = new XMLHttpRequest(); xhr.open("POST", "/task/testFile"); xhr.send(new FormData(formElement)); } </script>
The format is as follows:
Second, when calling the interface code
1. Use the application/x-www-form-urlencoded
encoding format to set the Request attribute calling interface in the code , which can be implemented as follows:
private static String doPost(String strUrl, String content) { String result = ""; try { URL url = new URL(strUrl); //通过调用url.openConnection()来获得一个新的URLConnection对象,并且将其结果强制转换为HttpURLConnection. HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("POST"); //设置连接的超时值为30000毫秒,超时将抛出SocketTimeoutException异常 urlConnection.setConnectTimeout(30000); //设置读取的超时值为30000毫秒,超时将抛出SocketTimeoutException异常 urlConnection.setReadTimeout(30000); //将url连接用于输出,这样才能使用getOutputStream()。getOutputStream()返回的输出流用于传输数据 urlConnection.setDoOutput(true); //设置通用请求属性为默认浏览器编码类型 urlConnection.setRequestProperty("content-type", "application/x-www-form-urlencoded"); //getOutputStream()返回的输出流,用于写入参数数据。 OutputStream outputStream = urlConnection.getOutputStream(); outputStream.write(content.getBytes()); outputStream.flush(); outputStream.close(); //此时将调用接口方法。getInputStream()返回的输入流可以读取返回的数据。 InputStream inputStream = urlConnection.getInputStream(); byte[] data = new byte[1024]; StringBuilder sb = new StringBuilder(); //inputStream每次就会将读取1024个byte到data中,当inputSteam中没有数据时,inputStream.read(data)值为-1 while (inputStream.read(data) != -1) { String s = new String(data, Charset.forName("utf-8")); sb.append(s); } result = sb.toString(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } return result; } public static void main(String[] args) { String str = doPost("http://localhost:8888/task/", "firstName=Mickey%26&lastName=Mouse "); System.out.println(str); }
2. When multipart/form-data
setting the Request property in the code using the encoding format to call the interface, boundary
the value in it can be specified when setting the Content-Type to let the server know how to split the parameters it accepts. Call the interface through the following code:
private static String doPost(String strUrl, Map<String, String> params, String boundary) { String result = ""; try { URL url = new URL(strUrl); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("POST"); urlConnection.setConnectTimeout(30000); urlConnection.setReadTimeout(30000); urlConnection.setDoOutput(true); //设置通用请求属性为multipart/form-data urlConnection.setRequestProperty("content-type", "multipart/form-data;boundary=" + boundary); DataOutputStream dataOutputStream = new DataOutputStream(urlConnection.getOutputStream()); for (String key : params.keySet()) { String value = params.get(key); //注意!此处是\r(回车:将当前位置移到本行开头)、\n(换行:将当前位置移到下行开头)要一起使用 dataOutputStream.writeBytes("--" + boundary + "\r\n"); dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + encode(key) + "\"\r\n"); dataOutputStream.writeBytes("\r\n"); dataOutputStream.writeBytes(encode(value) + "\r\n"); } //最后一个分隔符的结尾后面要跟"--" dataOutputStream.writeBytes("--" + boundary + "--"); dataOutputStream.flush(); dataOutputStream.close(); InputStream inputStream = urlConnection.getInputStream(); byte[] data = new byte[1024]; StringBuilder sb = new StringBuilder(); while (inputStream.read(data) != -1) { String s = new String(data, Charset.forName("utf-8")); sb.append(s); } result = sb.toString(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); } return result; } private static