Content-Type+前端axios传值方式---springboot接收前端参数方式

Content-Type+前端axios传值方式---springboot接收前端参数方式,第1张

知识巩固

先来熟悉下,前端给后端传值的时候有哪几种方式呢?

HTML标签的form表单提交(GET、POST方式提交)Jquery中的ajax方式提交其他的一些如axios(其实就是封装了ajax) GET、POST区别

那么说到了Form表单提交,有必要再去了解下,form表单中,提交方式get和post的区别,这里借用一下网上的图来说明一下。

一个HTTP请求,一般包含以下几个内容:

请求行(请求地址…)

请求头(头部信息…)

请求体(可存储数据)

请求空行(HTTP协议数据规范)

那么GET和POST提交方式的区别如上图所示:

在请求行中,POST方式不会把数据暴露出来,GET会暴露数据,但是GET方式处理数据的效率优于POST方式,根据情况取舍POST方式会把数据处理好后,放入到请求体中 Content-Type

Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件 --百度百科

说白了,就是比如两个人要进行数据的传递,那么这两个人定义好一个内容类型,一方以这种内容类型传递数据,另一方要遵守规定也以这种内容类型进行读取传输过来的数据。

Content-Type有哪些类型:(常见的)

application/x-www-form-urlencoded: 标准表单编码类型

请求体中的数据会以普通表单形式(键值对)发送到后端

multipart/form-data:类型

它会将请求体的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件

application/json: json类型

请求体中的数据会以json字符串的形式发送到后端

application/xml: xml类型

前端知识 使用axios时怎么传值

Content-Type: application/json时

let params = {'title':'test', 'sub' : [1,2,3]}
axios({
    method: 'post',
    url: '/api/lockServer/search',
    params
})

最终发送的请求是 
{"title":"test","sub":[1,2,3]}

Content-Type: application/x-www-form-urlencoded 时

不设置Content-Type,使用URLSearchParams

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

使用qs库编码数据(需要设置Content-Type)

import qs from 'qs';
const data = { 'bar': 123 };
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data: qs.stringify(data),
  url,
};
axios(options);

Content-Type: multipart/form-data时

采用FormData方式

import axios from 'axios'
let data = new FormData();
data.append('code','1234');
data.append('name','yyyy');
axios.post(`${this.$url}/test/testRequest`,data)
.then(res=>{
    console.log('res=>',res);            
})
request的Content-Type

一般我们在开发的过程中需要注意客户端发送请求(Request)时的Content-Type设置,特别是使用ajax的时候,如果设置得不准确,很有可能导致请求失败。比如在spring中,如果接口使用了@RequestBody,spring强大的自动解析功能,会将请求实体的内容自动转换为Bean,但前提是请求的Content-Type必须设置为application/json,否正就会返回415错误。
注:415 错误是 Unsupported media type,即不支持的媒体类型。
建议:

如果是一个restful接口(json格式),一般将Content-Type设置为application/json; charset=UTF-8;如果是文件上传,一般Content-Type设置为multipart/form-data如果普通表单提交,一般Content-Type设置为application/x-www-form-urlencoded response的Content-Type

服务端响应(Response)的Content-Type最好也保持准确,虽然一般web开发中,前端解析响应的数据不会根据Content-Type,并且服务端一般能自动设置准确的Content-Type,但是如果乱设置某些情况下可能会有问题,比如导出文件,打开图片等。如果在spring项目里使用@ResponseBody,spring会将响应的Content-Type设置为application/json;charset=UTF-8;,可能会导致文件无法导出,需要注意下。

建议:

一般情况下不需要显示设置;如果是文件导出,Content-Type 设置为 multipart/form-data,并且添加一个Content-Disposition设置为attachment;fileName=文件.后缀。(用springboot做过文件下载的应该比较熟悉这点)注:Content-Disposition是Content-Type的扩展,告诉浏览器d窗下载框,而不是直接在浏览器里展示文件。因为一般浏览器对于它能够处理的文件类型,如txt,pdf 等,它都是直接打开展示,而不是d窗下载框。 SpringBoot接收参数几种方式

进入正题。。

首先,学过springmvc应该知道,后端常用接收参数的几种方式有:

无注解 (普通类型、对象类型)

@RequestParam

@RequestBody

@PathVariable

HttpServletRequest

其中有一个小细节,可能大多数人都忽略了,那就是:

​ 当使用注解方式+限制必传(默认的就是必传)时,前端必须给我传这个参数,否则直接告诉他4xx(客户端错误),这个大家应该都知道。当使用无注解HttpServletRequest时,如果前端没有把值传过来或者数据丢了,那么后端不会去报错,而是给一个默认值(普通类型(比如int类型默认0)和引用类型的默认值(null)),继续执行代码。

无注解接收参数

先准备一个User类,方便后面使用

@Data
public class User {
    private String name;
    private String age;
}
// 普通类型
@GetMapping("/test1")
public void test1(String name, Integer age) {
    System.out.println(name);
    System.out.println(age);
}

// 对象类型
@GetMapping("/test2")
public void test2(User user) {
    System.out.println(user);
}
普通类型 数据放入请求行

还不清楚请求行的,去上面看一下介绍就明白了。

控制台打印:

zs
21
数据放入请求体

控制台打印:

zs
21
对象类型 数据放入请求行

控制台打印:

User(name=zs, age=21)
数据放入请求体

控制台打印:

User(name=zs, age=21)
结论

无论是普通类型还是对象类型,放入请求行还是请求体,都能把数据读取出来。

@RequestParam注解

使用@RequestParam注解时要注意,此注解一般使用在普通类型的属性上,因为对象类型的时候,你的值根本就不好传,当然像一些好传值的类型是可以用的,比如 List、数组…

@GetMapping("/test3")
public void test3(@RequestParam String name, @RequestParam String age) {
    System.out.println(name);
    System.out.println(age);
}

@GetMapping("/test4")
public void test3(@RequestParam List<Integer> ids) {
    System.out.println(ids);
}
普通类型 放入请求行

控制台打印:

zs
21
放入请求体

控制台打印:

zs
21
对象类型 放入请求行

控制台打印:

[1, 2, 3]
放入请求体

控制台打印:

[1, 2, 3]
结论

使用@RequestParam注解时,和不使用注解一样,都可以接收到请求行请求体中的数据。

但是要注意下,不使用注解时,不传值时会给属性默认值。

@RequestBody

使用@RequestBody,后端接收Content-Type是application/json类型的json数据,且数据都是放入请求体的,Content-Type如果不对,则会报错,一般就是不支持Content-Type类型之类的,协商一下改一下就行。

@GetMapping("/test6")
public void test6(@RequestBody User user) {
    System.out.println(user.toString());
}

@GetMapping("/test7")
public void test7(@RequestBody Map<String, Object> map) {
    System.out.println(map.toString());
}

@GetMapping("/test8")
public void test8(@RequestBody List<Integer> ids) {
    System.out.println(ids);
}

@GetMapping("/test9")
public void test9(@RequestBody int[] ids) {
    System.out.println(ids);
}
test6(User类型)

请求体中的数据

控制台输出:

User(name=zs, age=21)
test7(Map类型)

控制台输出:

{name=zs, age=21}
test8(集合类型)

控制台打印:

[1, 2, 3]

这里一定是要注意的:

当我们接收的是集合或者数组的时候,前端传过来的一定不能是json对象,而是一个json数组,切记!!!

test9就不演示了,和test8是一模一样的,也是接收的json数组。

@PathVariable

这种就是直接把参数值给拼接到url中,然后后端直接读取就可以了

当不传值时,由于url匹配不到,就直接404了

@GetMapping("/test5/{id}")
public void test5(@PathVariable Integer id) {
    System.out.println(id);
}

控制台打印:

1
HttpServletRequest

接收的参数就是一个HttpServletRequest对象,然后从这个Request对象里取数据即可。

@GetMapping("/test10")
public void test10(HttpServletRequest request) {
    String name = request.getParameter("name");
    String age = request.getParameter("age");
    String age2 = request.getParameter("age2");
    System.out.println(name);
    System.out.println(age);
    System.out.println(age2);
}
请求行

控制台打印:

zs
21
null
请求体

控制台输出:

zs
21
null
结论:

和其他方式一样,都可以从请求行和请求体中读取到数据。数据没有传输过来那就采用默认值的方式。

如果请求行和请求体都传数据

平时应该遇不到这样的问题,但是还是了解下吧,不然后面真遇到了,就直接蒙圈了。

请求行和请求体中传输的数据都是不同名的:

这种是没有任何问题的,相当于是我一些数据从请求行传过去,一些数据从请求体中传过去,能正常接收

请求行和请求体中传输的数据有同名的:

这种请求,我试了两个类型,其他的暂时没有试。如果是String类型的参数,那么它会先读取到请求体中的数据,请求行如果有同名的属性,那么会把值 拼接到从请求体读取到的数据上,逗号分割。如zs,ls

如果是Integer类型,那么它只会以请求体中的数据为准(同样是先读取请求体,然后如果请求行中有同名,直接过滤掉了–个人理解)

其他类型没有深究,有兴趣的可以去试试。如果后面遇到这种问题,这是一种排错的方式,仅供参考。

参考 Content-Type详解 Form表单的提交方式 SpringBoot 出现 Content type ‘application/x-www-form-urlencoded;charset=UTF-8’ not supported 前端axios配置Content-Type

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/945327.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存