json参数解析--源码

示例:

@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字符串,用流的方式返回请求端。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值