背景
作为一个初级菜鸟,写功能都是得过且过的状态,有时候自己也不明白是为什么实现了,为什么实现不了,本次是因为之前有个功能需要上传图片,需要把这个类型放到一个实体类里面,然后前端使用表单提交的,当时不明白网上有个帖子为什么说去掉@RequestBody注解,但是试了一试,可行,就完事了,所以现在又回过头来思考了一波。
结论(这段话是从网上看到的一段分析)
- 以前太年轻,没好好学sevlet,唉(这句话是我自己的)
- 在sevlet(这里指Tomcat)实现中,mutipart/form-data和application/x-www-form-urlencoded会被特殊处理,请求参数将被放置于request.paramter,这是一个map。
- 首先,服务器为什么会对表单提交和文件上传做特殊处理,因为表单提交数据是名值对的方式,且Content-Type为application/x-www-form-urlencoded,而文件上传服务器需要特殊处理,普通的POST请求(Content-Type不是application/x-www-form-urlencoded)数据格式不固定,不一定是名值对的方式,所以服务器无法知道具体的处理方式,所以只能通过获取原始数据流的方式来进行解析。
此时,默认的Cotent-type=text/plain,这时服务器就不知道怎么解析数据了,所以才只能通过获取原始数据流的方式来进行解析请求数据,不能使用@RequestParam绑定数据。Content-Type不是application/x-www-form-urlencoded的POST请求是不会读取请求体数据和进行相应的参数处理的,即不会解析表单数据来放到request parameter map中。所以通过request.getParameter(name)是获取不到的
环境
springboot ,Tomcat
multipart/form-data; boundary=(表单提交)
使用表单提交通常后端不能在参数上使用@RequestBody注解,也可能有什么特殊的类可以,但我不知道,我记录只是大部分的情况
- Content-Type=multipart/form-data; boundary=
获取方法一:使用对应key名直接接受
方法体
@PostMapping
@UserLoginToken
public ApiCommonResult insert(String loginUser ,String userName)
{
try {
System.out.println(loginUser);
System.out.println(userName);
return new ApiCommonResult(true,1,"success");
} catch (Exception e) {
e.printStackTrace();
return new ApiCommonResult(false,0,e.getMessage());
}
}
访问url
结果
获取方法二:使用对象接受,对象里面有包括前端传过来的属性,key名一致
方法体
@PostMapping
@UserLoginToken
public ApiCommonResult insert(User user)
{
try {
System.out.println(user);
return new ApiCommonResult(true,1,"success");
} catch (Exception e) {
e.printStackTrace();
return new ApiCommonResult(false,0,e.getMessage());
}
}
访问url
结果
获取方法三:还可以使用@RequestParam注解进行绑定
方法体
@PostMapping
@UserLoginToken
public ApiCommonResult insert(@RequestParam(value = "loginUser") String login ,@RequestParam(value = "userName") String u)
{
try {
System.out.println(login);
System.out.println(u);
return new ApiCommonResult(true,1,"success");
} catch (Exception e) {
e.printStackTrace();
return new ApiCommonResult(false,0,e.getMessage());
}
}
url
结果可以获取到
application/x-www-form-urlencoded
- Content-Type=application/x-www-form-urlencoded
表单的默认类型,上面表单可以获取方式,它都可以用,但是它本身还有一种,使用MultiValueMap,可以加上@RequestBody注解
方法体
@PostMapping("/test")
@UserLoginToken
@ApiOperation("数组")
public ApiCommonResult insert2(@RequestBody MultiValueMap<String,String> user)
{
try {
System.out.println(user);
return new ApiCommonResult(true,1,"success");
} catch (Exception e) {
e.printStackTrace();
return new ApiCommonResult(false,0,e.getMessage());
}
}
url
结果