示例:
@Controller
public class TestController {
@RequestMapping("/gmArea")
@ResponseBody
public GmArea gmArea(@RequestBody GmArea gmArea) {
gmArea.setAreaName("@ResponseBody测试返回");
return gmArea;
}
那么json参数是如何解析的,接着上一篇说,springMVC的请求调用流程到了DispatcherServlet类的doDispatcher方法之后,根据request获取了handler,又根据handler拿到了HandlerAdapter ,进行了前置拦截器的调用后,进入到HandlerAdapter 的反射调用,会调到以下方法:
代码片段一:
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//具体调用逻辑
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
.....
.....
try {
//返回值处理
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
.....
}
看代码片段一中的具体调用逻辑:
代码片段二:
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//获取参数数组
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
return doInvoke(args);
}
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//入参的包装类,里面包装了参数类型,参数名称,参数注解等等信息
MethodParameter[] parameters = getMethodParameters();
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_ARGS;
}
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
//设置参数名称解析器
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
//典型的策略模式,根据parameter能否找到对应参数的处理类,能找到就返回true
if (!this.resolvers.supportsParameter(parameter)) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
//具体参数值解析过程
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
}
.....
}
return args;
}
看代码片段二中具体的参数值解析过程:
代码片段三:
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
//根据参数获取对应参数的解析类
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException("Unsupported parameter type [" +
parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
}
//策略模式去调用具体参数解析类
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
在这里根据参数拿到的json参数解析类是:
除了支持@RequestBody注解,也支持@ResponseBody注解
接下来会遍历所有的消息转换器,根据策略模式找到匹配的消息转换器:
消息转换器从输入流里面拿参数,按照json格式来解析,最终包装成我们controller方法中定义的javaType类:
接下来拿到生成的参数,进行反射调用,调到controller中的具体方法
接下来会将返回对象按照json格式解析返回,会走到代码片段一中的返回值处理
视图渲染的时候会用到这个boolean类型的变量,判断是否响应视图。
返回值处理和参数解析类似,也是策略模式调用具体的返回值处理类,然后策略模式调用具体的消息转换器,把返回值包装成json字符串,用流的方式返回请求端。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/13816.html