Spring 4.3.0.RELEASE不会将模型和请求注入@Controller

时间:2016-06-10 13:50:34

标签: spring spring-mvc spring-4

下面的代码在Spring 4.2.6.REALESE中运行良好。现在,在迁移之后,某些内容发生了变化,我开始在@Controller中获取空值这是一个错误吗?

@Controller
@RequestMapping("/client")
public class ClientController {

  @RequestMapping(value = "test", method = RequestMethod.GET)
  public String test(Model model) { 
    // model is null at this point
    return "client/test";
  }
}

3 个答案:

答案 0 :(得分:1)

我与模型对象为空,分享您的经验。下面的代码在4.3.0-RELEASE之前运行良好。也许我们错过了一些新的配置?

@Controller
@RequestMapping("/admin/pricelists")
public class PriceListsController  {

    @RequestMapping(value = "/")
    public String index(final Model model) {
        // Model is null in 4.3.0-RELEASE.
        ...
    }
}

答案 1 :(得分:1)

简答:4.3.0.RELEASE需要Servlet 3.0 +

更长的证据:

模型为空,因为找到ArgumentResolver的正确org.springframework.ui.Model的方法会找到列表中的第一个org.springframework.web.method.annotation.RequestParamMethodArgumentResolver 而不是org.springframework.web.method.annotation.ModelMethodProcessor

这是代码形式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;
}

RequestParamMethodArgumentResolver首先出现在列表中 由于以下行,RequestParamMethodArgumentResolver.supportsParameter(MethodParameter parameter)返回true:

if (MultipartResolutionDelegate.isMultipartArgument(parameter)) {
                return true;
            }

然后在MultipartResolutionDelegate

public static boolean isMultipartArgument(MethodParameter parameter) {
    Class<?> paramType = parameter.getNestedParameterType();
    return (MultipartFile.class == paramType || isMultipartFileCollection(parameter) ||
            isMultipartFileArray(parameter) || servletPartClass == paramType ||
            isPartCollection(parameter) || isPartArray(parameter));
}

isPartCollection返回true,因为这个奇怪的比较,方程的两边都是空的!

private static boolean isPartCollection(MethodParameter methodParam) {
    return (servletPartClass == getCollectionParameterType(methodParam));
}
由于这个

servletPartClass为null

private static Class<?> servletPartClass = null;

    static {
        try {
            servletPartClass = ClassUtils.forName("javax.servlet.http.Part",
                    MultipartResolutionDelegate.class.getClassLoader());
        }
        catch (ClassNotFoundException ex) {
            // Servlet 3.0 javax.servlet.http.Part type not available -
            // Part references simply not supported then.
        }
    }

答案 2 :(得分:1)

4.3.1

中的is fixed
  

Spring Framework / SPR-14358
  无法在Servlet 2.5环境中解析@RequestMapping方法参数