本文简单介绍HTTP MediaType在Spring MVC中的处理方式,并通过实际项目场景加以分析。
Http请求中的ContentType与Accept
在HTTP协议中,ContentType用于向服务器描述客户端请求报文媒体类型,Accept用于描述客户端希望接收到的返回报文媒体类型。
ContentType与Accept在AJAX请求中格式如下:
$.ajax({
url: url,
type:"POST",
cache: false,
data:jsonDataStr,
dataType:"json",
contentType:"application/json",
headers: {"Accept":"application/json"},
success: function(data)
{
//todo:data为处理返回的数据,为json对象
},error: function() {
}
对应HTTP请求中表现形式如下:
Accept:application/json
Content-Type:application/json
SpringMVC常用Converter
在spring-web.jar中,定义了处理各种常见MediaType的Converter:
FormHttpMessageConverter:默认处理application/x-www-form-urlencoded及multipart/form-data媒体类型。
MappingJackson2HttpMessageConverter:默认处理application/json媒体类型,Spring3.1.2版本后从jackson1.X版本升级为jackson2.X版本。
StringHttpMessageConverter:默认处理所有未设置ContentType的请求。
ByteArrayHttpMessageConverter:默认处理application/octet-stream类型请求。
需要自定义媒体类型时,可以在SpringMVC配置文件中进行配置:
<bean class="org.springframework.web.servlet.mvc.method.annotation.
RequestMappingHandlerAdapter">
<property name="messageConverters">
<list><!--在此添加需要使用的converter,添加后原有默认的converter将不再可用。><ref bean="jsonConverter" /></list></property></bean><bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="supportedMediaTypes"><list><value>application/json</value><!--自定义处理MediaType--><value>text/json</value></list></property></bean>
Spring选择Converter的优先级如下:
1、请求中的ContentType和Accept对应的Converter
2、如果1无法找到对应Converter,则通过遍历MessageConverters的canRead/canWrite选择最有可能的Converter
3、如果2无法找到对应Converter,则返回错误。
常见媒体类型使用场景
application/x-www-form-urlencoded
在HTML中,该媒体类型为form表单提交默认的媒体类型,在请求BODY中,对象以URLEncoded的格式进行序列化,序列化后属性与值之间通过“=”进行键值匹配,属性之间通过“&”进行分割。
示例代码:
<form action="targetUrl" method="post">
<input type="text" name="userName"/>
<input type="text" name="password"/>
<input type="submit"/>
</form>
提交后BODY数据:
userName=admin&password=b59c67bf196a4758191e42f76670ceba
Spring Controller通过Method的入参或者request.getParameter获取传入参数。
@RequestMapping(value="/login")
public String login(HttpServletRequest request,HttpServletResponse response,
String userName,String password){
request.getParameter("userName");
request.getParameter("password");
return null;
}
multipart/form-data
在HTML中,该媒体类型用于处理包含文件流的表单请求。页面示例如下:
<form action="targetUrl" method="post" enctype="multipart/form-data">
<input type="file" name="uploade/>
<input type="submit"/></form>
提交后BODY数据(文件字节流无显示):
------WebKitFormBoundaryzFUmkVY8xZakacAp
Content-Disposition: form-data; name="upload"; filename="0_1474424040152845.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryzFUmkVY8xZakacAp--
Spring Controller中通过MultipartFile对象接收处理请求:
@RequestMapping(value = "/upload")
public String upload(HttpServletRequest request,HttpServletResponse response,MultipartFile upload){
//TODO:文件上传
return null;}
上传多个文件时,通过MulTipartFile数组进行处理。
application/json
application/json对应JSON格式数据,常用与AJAX请求与HTTP REST风格服务接口中。
请求中ContentType与Accept定义为application/json,Controller中通过ResponseBody进行返回。
请求:
var user={"name":"fisher","mark":"fisher demo"}
var jsonDataStr=JSON.stringify(user);
$.ajax({
url: url,
type:"POST",
cache: false,
data:jsonDataStr,
dataType:"json",
contentType:"application/json",
headers: {"Accept":"application/json"},
success: function(data)
{
if(data.code==1){
alert(data.message);
}
//todo:data为处理返回的数据,为json对象
},error: function() {
}
后台处理:
@RequestMapping(value = "/jsonhandle", method = RequestMethod.POST)
public @ResponseBody Map<String,Object> jsonHandle(User user){
Map<String,Object> result=new HashMap<String,Object>();
result.put("code",1);
result.put("message","this is a test");
return result;
}
Jquery Ajax中的dataType
当Jquery Ajax中dataType为text时,则Accept为application/json的请求会保留为纯文本字符,而不会生成JavaScript对象。
参考:w3school