Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json

本文主要是介绍Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前端表单提交时

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

 

我们可以看出,服务器知道参数用符号&间隔,如果参数值中需要&,则必须对其进行编码。编码格式就是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

 

文件上传

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

格式如下:

 

二、调用接口代码时

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)值为-1while (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-dataurlConnection.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的值如下:

 

三、使用Postman测试接口时

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

 

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

 

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

 

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

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

 

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

 

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

 

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

Java OK HTTP

 

JavaScript Jquery AJAX

JavaScript XHR

 

接口代码

@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();}

或者用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();}

使用postMan测试

这篇关于Post请求的3种编码格式:application/x-www-form-urlencoded和multipart/form-data和application/json的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130114

相关文章

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

SpringMVC获取请求参数的方法

《SpringMVC获取请求参数的方法》:本文主要介绍SpringMVC获取请求参数的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下... 目录1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数3、@RequestParam4、@

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

使用Python将JSON,XML和YAML数据写入Excel文件

《使用Python将JSON,XML和YAML数据写入Excel文件》JSON、XML和YAML作为主流结构化数据格式,因其层次化表达能力和跨平台兼容性,已成为系统间数据交换的通用载体,本文将介绍如何... 目录如何使用python写入数据到Excel工作表用Python导入jsON数据到Excel工作表用

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt

解决SpringBoot启动报错:Failed to load property source from location 'classpath:/application.yml'

《解决SpringBoot启动报错:Failedtoloadpropertysourcefromlocationclasspath:/application.yml问题》这篇文章主要介绍... 目录在启动SpringBoot项目时报如下错误原因可能是1.yml中语法错误2.yml文件格式是GBK总结在启动S

springboot filter实现请求响应全链路拦截

《springbootfilter实现请求响应全链路拦截》这篇文章主要为大家详细介绍了SpringBoot如何结合Filter同时拦截请求和响应,从而实现​​日志采集自动化,感兴趣的小伙伴可以跟随小... 目录一、为什么你需要这个过滤器?​​​二、核心实现:一个Filter搞定双向数据流​​​​三、完整代码

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,