《知识点扫盲 · 请求类型 ContentType》

news2024/12/29 9:43:53

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • 写在前面的话
    • 常见的 Content-Type 接收
      • application/json
      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/plain
      • application/xml
    • 实战运用
      • 类型不匹配的情况
      • Axios 针对不同 ContentType
    • 总结陈词

CSDN.gif

写在前面的话

Content-Type是HTTP头部的一部分,用于指示发送到HTTP请求或响应中的数据的格式和类型。在 SpringMVC 开发中,当处理HTTP请求时,Content-Type 非常重要,因为它告诉Spring如何解析请求体中的数据,以及如何设置响应的格式。
举个例子,打开谷歌浏览器,按F12打开开发者工具,此时访问某网站,可以在开发者工具查找接口调用情况。如下所示,查看任意请求,基本都可以看到请求头和响应头包含 Content-Type
先关注一下请求头的Content-Type,客户端发送请求的请求头里面的 Content-Type 告诉服务提供方如何解析和处理请求或响应中的数据,不同的 Content-Type 值对应不同的数据格式,服务器和客户端可以根据这个信息进行相应的处理。
image.png
本篇博文主要介绍一下 SpringMVC 开发中,针对客户端发起的不同请求类型,后端控制器参数部分应当如何处理。


常见的 Content-Type 接收

在 Spring MVC 开发中,常见的 Content-Type 值及其对应的接收方式如下:

application/json

**类型描述:**表示请求体是 JSON 格式的数据。
**接收方式:**使用 @RequestBody 注解来接收 JSON 数据,Spring 会自动将 JSON 转换为 Java 对象。
**参考源码:**RequestResponseBodyMethodProcessor
**补充说明:**日常开发中,这种方式应该使用较多。

@PostMapping(value = "/api/user", consumes = "application/json")
public ResponseEntity<User> createUser(@RequestBody User user) {
    
}

application/x-www-form-urlencoded

**类型描述:**表示请求体是表单数据,通常用于表单提交,如果在 HTTP 请求中没有显式设置 Content-Type,那么默认的 Content-Type 通常是此种格式。
**接收方式:**使用 @RequestParam 注解来接收单个参数,本质是 request.getParameterValues。
**使用场景:**这种格式通常用于 HTML 表单的提交,适合简单的数据传输。
**数据格式:**在这种格式下,表单数据会被编码为键值对的形式,多个键值对之间用 & 符号连接,键和值之间用 = 符号分隔。例如:name=John&age=30&city=NewYork
**参考源码:**RequestParamMethodArgumentResolver

@PostMapping(value = "/api/user", consumes = "application/x-www-form-urlencoded")
public ResponseEntity<User> createUser(@RequestParam String userName) {
}

Tips:也可以使用 @ModelAttribute 注解来接收整个表单数据并映射到 Java 对象。

multipart/form-data

**类型描述:**表示请求体包含文件上传和表单数据。用于文件上传场景,可以上传文件和其他表单数据。
**接收方式:**使用 MultipartFile 类型来接收上传的文件。

@PostMapping(value = "/api/upload", consumes = "multipart/form-data")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
    // 处理文件
}

Tips:常用于文件上传,但也可以使用 @RequestParam 注解接收文件和其他表单字段。

text/plain

描述:表示请求体是纯文本格式的数据。
接收:使用 @RequestBody 注解来接收文本数据。

application/xml

描述:表示请求体是 XML 格式的数据。
接收:使用 @RequestBody 注解来接收 XML 数据,Spring 会自动将 XML 转换为 Java 对象。

实战运用

类型不匹配的情况

当客户端(Postman)传递的请求类型是 application/x-www-form-urlencoded,但是依然用请求体方式传递参数,服务端用 @RequestBody 方式接收会怎么样?
如下图所示:
image.png
这个错误是入参解析器抛出的,SpringMVC 会根据注解找到 RequestResponseBodyMethodProcessor 用来处理入参,当执行到 readWithMessageConverters 方法的时候,会发现遍历所有参数转换器,都找不到可以处理这个请求类型的参数转换器,直接抛出异常了。
image.png

【扩展说明】
大部分情况,SpringMVC 提供了相应的方法接收,但请求参数可能千奇百怪,框架不可能帮我们面面俱到。
针对一些复杂的参数类型,建议自定义参数解析器或参数转换器,封装便捷的解决方案,造福开发人员。


Axios 针对不同 ContentType

这边以前端常用的请求插件 Axios 为例,介绍一下不同 ContentType 的场景下需要。
Axios 是一个非常流行的 JavaScript 库,基于 Promise 实现,用于在浏览器和 Node.js 环境中进行 HTTP 请求,详细可参考这篇博文《程序猿入职必会(7) · 前端请求工具封装》,这边不展开介绍了。

application/json
这是最常用的内容类型之一,表示请求体是 JSON 格式。
参数直接传递 JSON 对象格式即可,Axios 会自动将对象转换为 JSON 字符串。

import axios from 'axios';

const data = {
  name: '战神',
  age: 28
};

axios.post('https://example.com/api/user', data, {
  headers: {
    'Content-Type': 'application/json'
  }
});

application/x-www-form-urlencoded
这种类型用于发送表单数据,数据以键值对的形式编码在请求体中。
使用 qs.stringify 将对象转换为 URL 编码的字符串,再进行请求。
注意,这种方式,Axios 不会自动帮忙转换,要手动处理。

import axios from 'axios';
import qs from 'qs';

const data = {
  name: '战神',
  age: 28
};

axios.post('https://example.com/api/user', qs.stringify(data), {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

// 也可以使用这种方式
const params = new URLSearchParams();
params.append('name', 'John');
params.append('age', '30');

multipart/form-data
这种类型通常用于文件上传,数据以多部分形式编码在请求体中。
使用 FormData 对象来构建请求体,不需要手动设置 Content-Type,Axios 会自动处理。

import axios from 'axios';

const formData = new FormData();
formData.append('file', fileInput.files[0]); 

axios.post('https://example.com/api/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
})

源码扩展说明
大多数情况,Content-Type 也可以不显示的指定,Axios 会根据参数的类型自动设置相应的 Content-Type。
可以参考 Axios 的部分源码如下,比如判断参数符合isURLSearchParams格式,则直接设置form请求类型。

// transformRequest
if (utils$1.isURLSearchParams(data)) {
  headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);
  return data.toString();
}
var isFileList;
if (isObjectPayload) {
  if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {
    return toURLEncodedForm(data, this.formSerializer).toString();
  }
  if ((isFileList = utils$1.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {
    var _FormData = this.env && this.env.FormData;
    return toFormData(isFileList ? {
      'files[]': data
    } : data, _FormData && new _FormData(), this.formSerializer);
  }
}
if (isObjectPayload || hasJSONContentType) {
  headers.setContentType('application/json', false);
  return stringifySafely(data);
}

但还是建议加上,让自己的代码可读性更高。

总结一下
根据不同的 Content-Type,构造请求体的方式会有所不同。

  • 在发送 JSON 数据时,Axios 会自动处理序列化。
  • 对于 application/x-www-form-urlencoded,需要使用 qs 库进行处理。
  • 对于文件上传,使用 FormData 对象。

在设置请求头时,确保 Content-Type 与请求体的格式相匹配。


总结陈词

此篇文章针对Content-Type进行了知识扫码,仅供学习参考。
Content-Type 的不同值决定了如何接收和处理请求体中的数据,开发者需要根据实际需求选择合适的 Content-Type 和接收方式,以确保数据能够正确解析和处理。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

CSDN_END.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1987938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Lambda函数理解与应用

Lambda 函数是 Python 中一种简洁的定义简单匿名函数的方法。它们通常用于需要小型函数对象的地方&#xff0c;尤其是作为高阶函数&#xff08;如 map, filter, reduce&#xff09;的参数。Lambda 函数的语法非常紧凑&#xff0c;只允许包含一个表达式。 1、问题背景 理解Lamb…

《大型集团信息安全整体解决方案》:从策略到执行的全方位指南(169页PDF下载)

一、前言 本PPT是一份关于华润集团信息安全整体规划方案的详细报告&#xff0c;从集团信息安全建设需求分析、建设规划蓝图、方案设计成果说明、建设内容与指标等几个方案全面阐述了某大型集团信息安全整体解决方案&#xff0c;值得借鉴与参考。报告首先对华润集团当前的信息安…

ChatGPT首次被植入人类大脑:帮助残障人士开启对话

马斯克在脑机接口中最强大的竞争对手Synchron有了新的技术进展&#xff0c;他们首次将ChatGPT整合到其脑机系统中&#xff0c;以使瘫痪患者更容易控制他们的数字设备。Synchron凭借其独特的脑机接口&#xff08;BCI&#xff09;技术脱颖而出&#xff0c;该技术巧妙地运用了成熟…

yum-aptget对应积累

libssl-dev openssl-devel libsnappy-dev

线上扭蛋机小程序详解,扭蛋机带来的乐趣

在当下潮流文化风靡的时代中&#xff0c;扭蛋机作为潮玩娱乐休闲模式&#xff0c;受到了消费者的关注&#xff0c;同时吸引了无数创业者入局。 扭蛋机小程序是在互联网发展下的产物&#xff0c;借助互联网技术&#xff0c;为消费者打造一个集娱乐购物与智能扭蛋为一体的新型扭…

Java 中的序列化和反序列化是什么?

1. 序列化 序列化是将对象转换成可传输的字节序列格式的过程&#xff0c;便于存储和传输。 对象在JVM中是“立体”的&#xff0c;包含各种引用。为了网络传输&#xff0c;需要将这些引用“压扁”&#xff0c;包含必要的信息。 因为对象在JVM中可以认为是“立体”的&#xff0…

Go sdk下载和配置环境变量

本文目录 SDK下载环境变量配置测试 SDK下载 下载地址&#xff1a;https://golang.google.cn/dl/ 更多版本&#xff0c;找到1.9.2 我是win10 64位的&#xff0c;我找到这个下载 下载之后解压&#xff0c;可以看到bin文件夹。 环境变量配置 我的电脑 -> 属性 -> 高级…

跨越距离无缝协作,最新远程控制软件

远程控制与协作已成为推动社会进步与企业发展的重要力量。无论是跨国企业的全球协同办公&#xff0c;还是家庭用户间的远程技术支持&#xff0c;甚至是教育行业的在线教学&#xff0c;远程控制软件都扮演着至关重要的角色。 1.向日葵远程控制 链接一下&#xff1a;https://do…

初探 C++模板:开启高效编程之门

目录 模版的引入 泛型编程 模板的概念 模板的使用 函数模版 函数模板概念 函数模板格式 函数模板的原理 函数模板的实例化 模板参数的匹配原则 类模版 类模板的定义格式 类模板的由来 类模板的实例化 模板的总结 模版的引入 如下代码&#xff0c;我们想实现交换…

OMS 2.0至3.0升级项目成功案例:木九十

作为眼镜行业的标杆品牌木九十&#xff0c;近期成功完成了OMS系统从2.0版本到3.0版本的全面升级。此次升级旨在提升全渠道库存管理能力&#xff0c;优化与SAP系统的无缝对接&#xff0c;实现与WMS系统的全面集成&#xff0c;并改进加工业务、维修单、特权订单和小程序服务。通过…

Ubuntu 无法进行SSH连接,开启22端口

我们在VM中安装好Ubuntu 虚拟机后&#xff0c;经常需要使用Xshell等工具进行远程连接&#xff0c;但是会出现无法连接的问题&#xff0c;原因是Ubuntu中默认关闭了SSH 服务。 1、 查看Ubuntu虚拟机IP地址 2、 利用Tabby等工具进行远程连接 命令&#xff1a;ssh ip地址 这里就是…

Java包

目录 1.包基本介绍 应用场景 包的三大作用 包基本语法 2.包原理 包的本质分析 3.包快速入门 4.包的命名 命名规则 命名规范 5.常用的包 6.包的使用细节 如何引入包 注意事项和使用细节 1.包基本介绍 应用场景 包的三大作用 区分相同名字的类&#xff0c;类…

浏览器用户文件夹详解 - Extensions(十二)

1.Extensions 简洁 1.1 什么是Extensions Extensions是Chromium浏览器中用于存储用户安装的扩展程序的一个重要目录。每当用户从Chrome Web Store或其他来源安装扩展程序时&#xff0c;这些扩展程序的文件都会被下载并存储在这个中。通过管理Extensions&#xff0c;用户和开发…

【时时三省】Code::Blocks 17.12 软件的使用----创建c工程

目录 1&#xff0c;软件下载 2&#xff0c;软件安装 3&#xff0c;软件下载 4&#xff0c;创建工程 5&#xff0c;编译运行 6&#xff0c;调试代码 一&#xff1a;第一种场景调试&#xff1a; 二&#xff1a;第二种场景调试&#xff1a; 三&#xff1a;第三种场景调试 …

哪个牌子手持洗拖一机好?多款热门家用洗地机推荐

以前打扫卫生&#xff0c;每次拖地前都要先扫地&#xff0c;然后再用拖把拧水&#xff0c;拖完还要清洗拖把&#xff0c;整个过程既费时又费力&#xff0c;还容易弄脏手&#xff0c;更重要的是还会出现清洁不干净的情况。而洗地机作为一种集吸尘、拖地、洗地于一体的智能清洁设…

2_stm32定时中断点灯

定时器是个好东西啊~ 之前搞上层应用时&#xff0c;通过定时器可以以某种频率刷新状态&#xff0c;stm32定时器的一种功能就是如此。此外&#xff0c;stm32的定时器还有很多其他功能&#xff0c;如PWM输出等。定时器具体再细分可以分为高级控制定时器、通用定时器、基本定时器等…

stm32应用、项目、调试

主要记录实际使用中的一些注意点。 1.LCD1602 电路图&#xff1a; 看手册&#xff1a;电源和背光可以使用5v或者3.3v&#xff0c;数据和控制引脚直接和单片机引脚连接即可。 单片机型号&#xff1a;stm32c031c6t6 可以直接使用推完输出连接D0--D7,RS,EN,RW引脚&#xff0c;3…

uni-app可替换radio-group的控件uni-segmented-control(十九)

【前言】 以前写过一篇对radio-group中的元素进行分列展示的文章,有兴趣的朋友可以看以下uni-app将radio-group元素分列展示(七):专栏管理-CSDN创作中心https://mp.csdn.net/mp_blog/manage/column/columnManage/12711831当时主要是因为radio-group中的元素过多,如果利用手…

600道大模型面试题,看完它手撕面试官,非常详细收藏我这一篇就够了

大模型面试题及答案 什么是大模型&#xff1f; 答&#xff1a; 大模型通常指的是那些拥有大量参数&#xff08;例如数十亿甚至更多&#xff09;的人工智能模型&#xff0c;这些模型经过大规模数据集的训练&#xff0c;能够处理复杂的任务。大模型的一个重要特点是它们往往能够捕…

977. 有序数组的平方(双指针)

目录 一题目: 二&#xff1a;代码&#xff1a; 三&#xff1a;结果&#xff1a; 一题目: 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 二&#xff1a;代码&#xff1a; class Solution…