SpringMVC
HTTP请求定义不同Content-Type及在SpringMVC如何接收
结论
1,get请求时是否定义Content-Type并无很大的影响,因为get没有请求体,所有的数据都是通过url带过去,所以必须是key=value的格式,所以在springmvc端使用@RequestParam String id这种格式即可,或者不写@RequestParam也可以,不写的话默认是@RequestParam。
2,除get外的这几种(POST、DELETE、PUT、PATCH)都是有请求体(body)的,且他们之间的差异不大,所以归在一起:
当请求时定义Content-Type为application/json; charset=utf-8时,请求体中的数据(不管是不是json格式)都只能用@RequestBody获取,且一个方法参数列表最多写一个@RequestBody,当然你也可以在请求url上带其他的queryString参数,然后再springmvc使用String id或@RequestParam String id获取。再次重申是这种情况下@RequestParam是无法获取请求体(body)中的参数的,springmvc会报错:Required String parameter ‘name’ is not present。所以这种情况只能使用@RequestBody获取请求体中的参数。至于你使用Bean接收还是String接收取决你的需求,Bean接收更方便,不需要再次反序列化,而String接收可以更灵活,可以对接收到的字段进行检查。
当请求时未定义Content-Type(默认为application/x-www-form-urlencoded; charset=UTF-8),请求体中的数据都必须是key=values的类型,可以是使用@RequestBody获取整个请求体中的多个参数,也可以使用@RequestParam获取单个参数
实验
首先我说明一下我测试的思路及流程,我后台使用的是springmvc,然后我在后台定义了一个接口,然后我使用js放入chrom的console下去执行。将每次执行结果记录下来,然后改变Content-Type再实验,对于Content-Type我只实验了两种:application/json; charset=utf-8 和 application/x-www-form-urlencoded; charset=UTF-8因为这两种是比较常用的对我而言。HTTP方法我试验了5种:GET、POST、DELETE、PUT、PATCH相对来说这几种还是用的比较多。SpringMVC中涉及的注解:@RequestBody、@RequestParam、@RequestMapping等
js请求代码
$.ajax({
url: "http://localhost:9080/api/thirdparty/policy?id=1",
dataType: "json",
//data: "fields='55'",
data: "name='abc'",
//data: "{'name':'abc'}",
//data: "{'name':'abc'}",
headers: {
'Accept': "application/json; charset=utf-8"
},
type: "post",
//type: "get",
//type: "delete",
//type: "patch",
//type: "put",
async: true,
//contentType: "application/json; charset=utf-8",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function(res) {
alert(JSON.stringify(res));
},
error: function(e) {
alert('系统错误!');
}
});
```
GET请求的结果
```text
GET
url//请求的url
http://localhost:9080/api/thirdparty/policy?id=1
header//请求时header中携带的参数
Content-Type:application/json; charset=utf-8 //是否定义没啥区别
queryString//请求时携带的参数
name=abc //无法定义成json格式,必须是key=value格式
springmvc//后台接收的方式
String name
@RequestParam String name //有无@RequestParam都行
//无法使用@RequestBody,因为get没有body
POST请求的结果
POST
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type未定义 //默认值Content-Type:application/x-www-form-urlencoded; charset=UTF-8
body
name=abc //若body中的是json格式数据如:"{'name':'abc'}",则后台无法获取到参数name,从而无法访问接口
springmvc
@RequestBody String name
name="abc"
String id
id="1"
POST
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type:application/json; charset=utf-8
body
{'name':'abc'}
springmvc
@RequestBody String body //@RequestBody是获取request的整个body体的数据,并且只能获取body中的数据,如果body中没有json数据,请求则报错Required request body is missing:
body="{'name':'abc'}"
String id
id="1"
POST
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type未定义 //默认值Content-Type:application/x-www-form-urlencoded; charset=UTF-8
body
{'name':'abc'}
springmvc
@RequestBody String body //这时的@RequestBody是获取queryString的参数+body参数URL编码后的值,因为有{}字符
body="id=1&%7B%27name%27%3A%27abc%27%7D="
@RequestParam String id
id="1"
POST
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
body
name=abc
springmvc
@RequestBody String body //这时的@RequestBody是获取queryString的参数+body参数URL编码后的值
body="id=1&name=abc"
@RequestParam String id
id="1"
DELETE请求的结果
DELETE
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type未定义 //默认值Content-Type:application/x-www-form-urlencoded; charset=UTF-8
body
name=abc
springmvc
@RequestBody String body //这时的@RequestBody是获取整个body数据,注意和post不同哦
body="name=abc"
@RequestParam String id
id="1"
DELETE
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type:application/json; charset=utf-8
body
{'name':'abc'}
springmvc
@RequestBody String body //这时的@RequestBody是获取整个body数据,同样请求时未有body数据就报错
body="{'name':'abc'}"
@RequestParam String id
id="1"
PUT请求结果
PUT
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type未定义 //默认值Content-Type:application/x-www-form-urlencoded; charset=UTF-8
body
{'name':'abc'}
springmvc
@RequestBody String body //这时的@RequestBody是获取整个body数据,同样请求时未有body数据就报错
body="{'name':'abc'}"
@RequestParam String id
id="1"
PUT
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type:application/json; charset=utf-8
body
{'name':'abc'}
springmvc
@RequestBody String body //这时的@RequestBody是获取整个body数据,同样请求时未有body数据就报错
body="{'name':'abc'}"
@RequestParam String id
id="1"
PATCH请求结果
PATCH
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type:application/json; charset=utf-8
body
{'name':'abc'}
springmvc
@RequestBody String body //这时的@RequestBody是获取整个body数据,同样请求时未有body数据就报错
body="{'name':'abc'}"
@RequestParam String id
id="1"
PATCH
url
http://localhost:9080/api/thirdparty/policy?id=1
header
Content-Type未定义 //默认值Content-Type:application/x-www-form-urlencoded; charset=UTF-8
body
{'name':'abc'}
springmvc
@RequestBody String body //这时的@RequestBody是获取整个body数据,同样请求时未有body数据就报错
body="{'name':'abc'}"
@RequestParam String id
id="1"
Content-Type
MediaType,即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。
类型格式:type/subtype(;parameter)? type
主类型,任意的字符串,如text,如果是*号代表所有;
subtype 子类型,任意的字符串,如html,如果是*号代表所有;
parameter 可选,一些参数,如Accept请求头的q参数, Content-Type的 charset参数。
例如: Content-Type: text/html;charset:utf-8;
常见的媒体格式类型如下:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
以application开头的媒体格式类型:
application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
以上就是我们在日常的开发中,经常会用到的若干content-type的内容格式
再比如tomcat服务器的 “conf/web.xml”中指定了扩展名到媒体类型的映射,在此我们可以看到服务器支持的媒体类型。
更多http支持的Content-type请在这里查看:http://www.runoob.com/http/http-content-type.html
2,HTTP方法(get,post…)
这是我在做resetFul的接口后才慢慢了解的。下面简单介绍如何使用
功能 | 请求 |
---|---|
获取用户列表 | GET:http://xxx.xxx.xxx.x/api/v1/users |
获取单个用户 | GET:http://xxx.xxx.xxx.x/api/v1/users/{uid:.{32}} |
创建单个用户 | POST:http://xxx.xxx.xxx.x/api/v1/users/{uid:.{32}} |
完全替换用户 | PUT:http://xxx.xxx.xxx.x/api/v1/users/{uid:.{32}} |
局部更新用户 | PATCH:http://xxx.xxx.xxx.x/api/v1/users/{uid:.{32}} |
删除单个用户 | DELETE:http://xxx.xxx.xxx.x/api/v1/users/{uid:.{32}} |
3,@RequestMapp
首先我们来看看RequestMapping中的Class定义
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String[] value() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
- value: 指定请求的实际地址, 比如 /action/info之类。
- method: 指定请求的method类型, GET、POST、PUT、DELETE等
- consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
- produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回,如果request请求头中的(Accept)类型中未包含produces定义数据类型的则无法访问接口
- params: 指定request中必须包含某些参数值是,才让该方法处理
- headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求其中,consumes, produces使用content-typ信息进行过滤信息;headers中可以使用content-type进行过滤和判断。
示例:
@RequestMapping( value = {"/policy"}, method = RequestMethod.POST, consumes="application/json", headers="Referer=http://www.csdn.com/*", produces = "application/json;charset=UTF-8")
public String post(HttpServletRequest request, @RequestParam String name, @RequestParam String id) {
System.out.println(name);
return BaseResultHP.jsonResultSuccess();
}
上述例子中:
consumes=”application/json”说明这个接口只处理Content-Type=”application/json”的请求
headers=”Referer=http://www.csdn.com/“
表示request请求头中必须包含Referer=http://www.csdn.com/ produces = “application/json;charset=UTF-8”会与请求头中的Accept进行匹配,如果Accept中也包含application/json,这时才返回数据,如果Accept中没有定义application/json,则服务器端会报错:Could not find acceptable representation 当你有如下Accept头,将遵守如下规则进行应用
①Accept:text/html,application/xml,application/json
将按照如下顺序进行produces的匹配 ①text/html ②application/xml ③application/json
②Accept:application/xml;q=0.5,application/json;q=0.9,text/html
将按照如下顺序进行produces的匹配 ①text/html ②application/json ③application/xml
参数为媒体类型的质量因子,越大则优先权越高(从0到1)
③Accept:*/*,text/*,text/html
将按照如下顺序进行produces的匹配 ①text/html ②text/* ③*/*
即匹配规则为:最明确的优先匹配