日常使用springboot项目经常碰到参数传递,最终接口却没有正常收到,或者收到参数缺失的场景,刚入行时对参数缺失的现象比较迷茫,又不知具体如何排查,往往最后就改下类型或者修改下属性名称然后可能就莫名奇妙好了。
今天有遇到一个post请求 Content-Type=application/json;charset:UTF-8,使用jackson,待属性中带name字段的值不能正常传递。
忽略前面的springMvc转发流程,直接定位核心排查类:
org.springframework.web.method.support.InvocableHandlerMethod
invokeForRequest这个方法就是将request转换成Controller中mapper对应的参数
其中如下段代码就是返会参数列表
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
/**
* Get the method argument values for the current request, checking the provided
* argument values and falling back to the configured argument resolvers.
* <p>The resulting array will be passed into {@link #doInvoke}.
* @since 5.1.2
*/
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
....
for (int i = 0; i < parameters.length; i++) {
.....
try {
//使用解析器进行参数解析
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
}
catch (Exception ex) {
...
throw ex;
}
}
return args;
}
然后进入另一个核心相关类:
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
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);
}
以jackson为例,最终获得的解析器是:
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter
然后我的问题是我们系统里面给AbstractJackson2HttpMessageConverter的ObjectMapper对象没有配置
objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES,true);
配置完后解决问题。