• HandlerMethodArgumentResolver数据绑定无效


      因项目中action参数过多,并且是一些通用的查询参数,所以准备进行对参数统一封装为Map对象,然后由action中传入service中进行处理,查询spring的资料发现可以通过实现HandlerMethodArgumentResolver进行数参数的绑定,参考文章《扩展SpringMVC以支持更精准的数据绑定1》进行配置后。

      项目调试中发现断点不能正常进行解析器,跟踪源代码找到在org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.getArgumentResolver()方法中会获取所有已经加载的解析器,会顺序执行,而我使用的Map对象会被spring自带的解析器给处理掉,所以自定义的解析器无法进入,HandlerMethodArgumentResolverComposite关键代码:

        private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
            HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
            if (result == null) {
                for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
                                parameter.getGenericParameterType() + "]");
                    }
                    if (methodArgumentResolver.supportsParameter(parameter)) {
                        result = methodArgumentResolver;
                        this.argumentResolverCache.put(parameter, result);
                        break;
                    }
                }
            }
            return result;
        }

    其中this.argumentResolvers为LinkedList变量,元素内容:

    [org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@9dc12fc,
    org.springframework.web.method.annotation.RequestParamMapMethodArgumentResolver@23c893fc,
    org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver@456b97be,
    org.springframework.web.servlet.mvc.method.annotation.PathVariableMapMethodArgumentResolver@1ab75e8d,
    org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMethodArgumentResolver@7ca088ae,
    org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMapMethodArgumentResolver@f6d976e,
    org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@63f0beab,
    org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor@5275ffcf,
    org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver@40ed9954,
    org.springframework.web.method.annotation.RequestHeaderMethodArgumentResolver@2eed7b19,
    org.springframework.web.method.annotation.RequestHeaderMapMethodArgumentResolver@692cbe60,
    org.springframework.web.servlet.mvc.method.annotation.ServletCookieValueMethodArgumentResolver@7886c691,
    org.springframework.web.method.annotation.ExpressionValueMethodArgumentResolver@58569768,
    org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver@1cee5a27,
    org.springframework.web.servlet.mvc.method.annotation.ServletResponseMethodArgumentResolver@6460c547,
    org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor@d37ebcd,
    org.springframework.web.servlet.mvc.method.annotation.RedirectAttributesMethodArgumentResolver@5259e682,
    org.springframework.web.method.annotation.ModelMethodProcessor@c2c8b0b,
    org.springframework.web.method.annotation.MapMethodProcessor@405c856b,
    org.springframework.web.method.annotation.ErrorsMethodArgumentResolver@7a3b54cf,
    org.springframework.web.method.annotation.SessionStatusMethodArgumentResolver@4d3d20ba,
    org.springframework.web.servlet.mvc.method.annotation.UriComponentsBuilderMethodArgumentResolver@682fbaf3,
    com.catt.web.springmvc.RequestMapResolver@159adcf5,
    org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@6a2063e7,
    org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@747f091f]

    红色标注出来的RequestParamMapMethodArgumentResolver为处理Map参数的解析器,处理关键代码:

        public boolean supportsParameter(MethodParameter parameter) {
            RequestParam requestParamAnnot = parameter.getParameterAnnotation(RequestParam.class);
            if (requestParamAnnot != null) {
                if (Map.class.isAssignableFrom(parameter.getParameterType())) {
                    return !StringUtils.hasText(requestParamAnnot.value());
                }
            }
            return false;
        }
    Map.class.isAssignableFrom会拦截实现Map接口的参数,所以我自定义的解析器始终无法断点进入。
  • 相关阅读:
    mysql 不能远程连接
    ajax 内部值 外部调用不了原因
    vm NAT方式linux上不了网 解决方法
    wordpress 在linux上配置固定url方法
    win8 报file://CBD 0xc0000034 蓝屏
    VM 打开虚拟机时报“内部错误”
    thinkphp 前后版本ajaxReturn方法的分别
    thinkphp3.2引入php 实例化类
    putty 实现不用输入用户名密码直接登陆
    jQuery 遍历
  • 原文地址:https://www.cnblogs.com/myssh/p/5421500.html
Copyright © 2020-2023  润新知