Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (2024)

一、前端表单提交时

application/x-www-form-urlencoded

表单代码:

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

通过测试发现可以正常访问接口,在Chrome的开发者工具中可以看出,表单上传编码格式为application/x-www-form-urlencoded(Request Headers中),参数的格式为key=value&key=value

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (1)

我们可以看出,服务器知道参数用符号&间隔,如果参数值中需要&,则必须对其进行编码。编码格式就是application/x-www-form-urlencoded将键值对的参数用&连接起来,如果有空格,将空格转换为+加号;有特殊符号,将特殊符号转换为ASCII HEX)。

application/x-www-form-urlencoded是浏览器默认的编码格式。对于Get请求,是将参数转换?key=value&key=value格式,连接到url后

ps:可以在这个网址测试表单:http://www.runoob.com/try/try.php?filename=tryhtml_form_submit

multipart/form-data

那么当服务器使用multipart/form-data接收POST请求时,服务器怎么知道每个参数的开始位置和结束位置呢?

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

我们在开发者工具中可以看出multipart/form-data不会对参数编码,使用的boundary(分割线),相当于&boundary的值是----Web**AJv3

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (2)

文件上传

上传文件也要指定编码格式为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>

如果是SpringMVC项目,要服务器能接受multipart/form-data类型参数,还要在spring上下文配置以下内容,SpringBoot项目则不需要

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"></property></bean>

我们可以通过FormData对象模拟表单提交,用原始的XMLHttpRequest来发送数据,让我们可以在Chrome开发工具中查看到具体格式:

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

格式如下:

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (3)

二、调用接口代码时

1、在代码中使用application/x-www-form-urlencoded编码格式设置Request属性调用接口,可以如下实现:

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、在代码中使用multipart/form-data编码格式设置Request属性调用接口时,其中boundary的值可以在设置Content-Type时指定,让服务器知道如何拆分它接受的参数。通过以下代码的调用接口:

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 String encode(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, "UTF-8");}public static void main(String[] args) { Map<String, String> params = new HashMap<>(); params.put("firstName", "Mickey"); params.put("lastName", "Mouse"); //自定义boundary,有两个要求:使用不会出现在发送到服务器的HTTP数据中的值;并在请求消息中的分割位置都使用相同的值 String boundary = "abcdefg"; String str = doPost("http://localhost:8888/testFile", params, boundary); System.out.println(str);}

通过debug,可以看出dataOutputStream的值如下:

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (4)

三、使用Postman测试接口时

1、POST请求 -> Body -> x-www-form-urlencoded

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (5)

当切换为x-www-form-urlencoded时,Headers会自动添加Content-Type:application/x-www-form-urlencoded

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (6)

当请求Send后,此时点Code,可以查看到和Chrome开发工具中(Request Headers处的Content-Type和Form Data)一样的数据

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (7)

2、POST请求 -> Body -> form-data

相当于html表单请求,value可为Text或文件。

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (8)

可以不用手动指定编码格式,也可以指定编码为multipart/form-data

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (9)

划线处的分割线应该是被省略了。

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (10)

可以更改左上角的类型,来查看相应的Headers代码,常见的是下面三种:

Java OK HTTP

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (11)

JavaScript Jquery AJAX

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (12)

JavaScript XHR

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (13)

接口代码

@RequestMapping("/task")public class TaskController { @RequestMapping("/") public String index(String firstName, String lastName) { //也可以从request中接收 //String firstName= request.getParameter("firstName")==null?"":request.getParameter("firstName").toString(); return firstName + lastName; } @RequestMapping("/testFile") public String testFile(String firstName, String lastName, MultipartFile file) { String result = firstName + lastName; if (file != null) { result += (file.getOriginalFilename() != null) ? file.getOriginalFilename() : ""; } return result; }}

POST请求的两种编码格式:application/x-www-urlencoded是浏览器默认的编码格式,用于键值对参数,参数之间用&间隔;multipart/form-data常用于文件等二进制,也可用于键值对参数,最后连接成一串字符传输(参考Java OK HTTP)。

除了这两个编码格式,还有application/json也经常使用。

application/json调用方式如下:

a) 使用httpClient

import org.apache.http.HttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import com.alibaba.fastjson.JSONObject;public class Sender { public static void main(String[] args) { String jsonData = ""; try{ CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost post = new HttpPost("http://127.0.0.1:8091/json/data"); post.addHeader("Content-Type", "application/json; charset=utf-8"); // 设置请求body信息 JSONObject body = new JSONObject(); body.put("name", "wangru"); body.put("address", "jinan"); post.setEntity(new StringEntity(body.toString())); HttpResponse response = httpClient.execute(post); jsonData = EntityUtils.toString(response.getEntity()); jsonData = UnicodeUtil.decodeUnicode(jsonData); System.out.println("接收反馈:"+jsonData);}catch(Exception e){ System.out.println(e.getMessage());}}}

b) 或者直接把数据写进流

public static String sendMessage4Json(){String jsonData = ""; OutputStreamWriter out = null ; BufferedReader in = null; StringBuilder result = new StringBuilder(); String url = "http://127.0.0.1:8091/json/data"; logger.info("请求url:"+url); try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); //设置通用的请求头属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Accept-Charset", "UTF-8"); conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); // 发送POST请求必须设置如下两行 否则会抛异常(java.net.ProtocolException: cannot write to a URLConnection if doOutput=false - call setDoOutput(true)) conn.setDoOutput(true); conn.setDoInput(true); //获取URLConnection对象对应的输出流并开始发送参数 out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); //添加参数 String json = "{\"name\":\"wangru\",\"address\":\"jinan\"}"; out.write(new String(json.getBytes("UTF-8"))); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8")); String line; while ((line = in.readLine()) != null) { result.append(line); } } catch (Exception e) { e.printStackTrace(); logger.info(e.getMessage()); }finally {// 使用finally块来关闭输出流、输入流 try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); logger.info(ex.getMessage()); } } logger.info("接收反馈:"+result.toString()); jsonData = result.toString(); return jsonData;} public static void main(String[] args) { sendMessage4Json();}

application/json接收方式如下:

@ResponseBody @RequestMapping(value = "/json/data3", method = RequestMethod.POST) public String getByJSON3 (HttpServletRequest request) { JSONObject result = new JSONObject(); StringBuilder sb = new StringBuilder(); InputStream is = null; try { is = request.getInputStream(); byte[] b = new byte[4096]; for (int n; (n = is.read(b)) != -1;) { sb.append(new String(b, 0, n)); } } catch (IOException e) { e.printStackTrace(); } finally { if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } result.put("json", sb); return result.toJSONString(); }

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (14)

或者用SpringBoot接收

 @ResponseBody @RequestMapping(value = "/json/data4", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String getByJSON4(@RequestBody JSONObject jsonParam) { JSONObject result = new JSONObject(); result.put("msg", "ok"); result.put("data", jsonParam); return result.toJSONString(); }

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (15)

使用postMan测试

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (16)

Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json_post request body form url encoded 格式-CSDN博客 (2024)
Top Articles
Latest Posts
Article information

Author: Barbera Armstrong

Last Updated:

Views: 6343

Rating: 4.9 / 5 (79 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Barbera Armstrong

Birthday: 1992-09-12

Address: Suite 993 99852 Daugherty Causeway, Ritchiehaven, VT 49630

Phone: +5026838435397

Job: National Engineer

Hobby: Listening to music, Board games, Photography, Ice skating, LARPing, Kite flying, Rugby

Introduction: My name is Barbera Armstrong, I am a lovely, delightful, cooperative, funny, enchanting, vivacious, tender person who loves writing and wants to share my knowledge and understanding with you.