json参数解析–源码

导读:本篇文章讲解 json参数解析–源码,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

示例:

@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

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!