1.@RequestBody与@ResponseBody的作用
@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。
@ResponseBody注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端
2.执行过程分析
基于org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor分析,该类的作用就是处理@RequestBody的读和@ResponseBody的写,参考文档:
/**
* Resolves method arguments annotated with {@code @RequestBody} and handles
* return values from methods annotated with {@code @ResponseBody} by reading
* and writing to the body of the request or response with an
* {@link HttpMessageConverter}.
*/
a)@RequestBody执行过程分析:
//在RequestResponseBodyMethodProcessor中
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//request参数的读
Object argument = readWithMessageConverters(webRequest, parameter, parameter.getGenericParameterType());
...
//进入上面调用的readWithMessageConverters方法
//在该方法中,调用了父类的方法
return super.readWithMessageConverters(inputMessage, methodParam, paramType);
//被调用的方法在:
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters(org.springframework.http.HttpInputMessage, org.springframework.core.MethodParameter, java.lang.reflect.Type)
//该方法通过查找合适的转换器,返回参数:@return the created method argument value
//readWithMessageConverters方法返回后,将参数绑定
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Object argument = readWithMessageConverters(webRequest, parameter, parameter.getGenericParameterType());
String name = Conventions.getVariableNameForParameter(parameter);
WebDataBinder binder = binderFactory.createBinder(webRequest, argument, name);
if (argument != null) {
validate(binder, parameter);
}
mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
return argument;
}
b)@ResponseBody执行过程分析
//RequestResponseBodyMethodProcessor类中
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
throws IOException, HttpMediaTypeNotAcceptableException {
mavContainer.setRequestHandled(true);
if (returnValue != null) {
writeWithMessageConverters(returnValue, returnType, webRequest);
}
}
//setRequestHandled:Signal a scenario where the request is handled directly.handle已经出处理
/**
* Writes the given return value to the given web request. Delegates to
* {@link #writeWithMessageConverters(Object, MethodParameter, ServletServerHttpRequest, ServletServerHttpResponse)}
*/
protected <T> void writeWithMessageConverters(T returnValue,
MethodParameter returnType,
NativeWebRequest webRequest)
throws IOException, HttpMediaTypeNotAcceptableException {
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}
//上面的方法执行这个,找到合适的转换器,转换数据格式
//该方法作用:Writes the given return type to the given output message.
//将数据写入ServletServerHttpResponse outputMessage,也就是Response中
protected <T> void writeWithMessageConverters(T returnValue,
MethodParameter returnType,
ServletServerHttpRequest inputMessage,
ServletServerHttpResponse outputMessage)
throws IOException, HttpMediaTypeNotAcceptableException
3.使用(转换成json)
这里转换成json:json最常用
配置json转换器:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</list>
</property>
</bean>
如果使用了<mvc:annotation-driven />
则不需要配置json转换器,因为
在其实现org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
中加入了:messageConverters.add(createConverterBeanDefinition(MappingJacksonHttpMessageConverter.class, source));
1)例如:用户验证(请求key/value类型,返回json):
//用户名验证
@RequestMapping("/checklogin")
public @ResponseBody User checkLogin(String username)throws Exception{
User user = new User();
if(userService.UserExist(username)){
user.setUsername(username);
}
return user;
}
$(document).ready(function(){
$("input.name").blur(function(){
$.ajax({
type:'post',
url:'${pageContext.request.contextPath }/checklogin.action',
//请求是key/value这里不需要指定contentType,因为默认就是key/value类型
data:'username='+$("input.name").val(),
success:function(data){//返回json结果
var mess;
if(!(data.username)){
mess="user not exist";
}
else
{
mess="user existed";
}
$("#errorTips").text(mess);
}
});
});
});
2)例如:请求json,返回json:
<input type="button" onclick="requestJson()" value="请求json,输出json"/>
function requestJson() {
$.ajax({
type:'post',
url:'${pageContext.request.contextPath }/requestJson.action',
contentType:'application/json;charset=utf-8',
//数据格式是json串,商品信息
data:'{"name":"手机","price":999}',
success:function(data){//返回json结果
alert(data);
}
});
}
@RequestMapping("/requestJson")
public @ResponseBody ItemsCustom requestJson(@RequestBody ItemsCustom itemsCustom){
return itemsCustom;
}