【问题标题】:Spring MVC 3.0 Model Attribute InheritanceSpring MVC 3.0 模型属性继承
【发布时间】:2011-11-25 18:23:59
【问题描述】:

我不确定这在 Spring MVC 3.0 中是否可行,但我正在尝试创建一个带注释的控制器,该控制器扩展另一个控制器,其模型属性取决于父级设置的模型属性。例如:

@Controller
public abstract class ParentModel {

    @ModelAttribute("numbers")
    protected List<Integer> getNumbers() {
        return Arrays.asList(new Integer(1));
    }

}

@Controller
public abstract class ChildModel extends ParentModel {

    @ModelAttribute("number")
    protected Integer getNumber(@ModelAttribute("numbers") List<Integer> numbers) {
        return numbers.get(0);
    }

}

@Controller
public class RequestHandler extends ChildModel {

    @RequestMapping("/number")
    public String items(@ModelAttribute("number") Integer number) {
        return "number"; // number.jsp
    }

}

到目前为止,我一直无法让它工作 - 它会引发以下异常:

请求处理失败;嵌套异常是 org.springframework.beans.BeanInstantiationException: 无法实例化 bean 类 [java.util.List]: Specified class is an interface] 根本原因 org.springframework.beans.BeanInstantiationException:无法实例化bean类[java.util.List]:指定的类是一个接口 在 org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101) 在 org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveModelAttribute(HandlerMethodInvoker.java:762) ...等 ...

当从 ChildModel.getNumber() 中移除对父级设置的属性的依赖时(通过移除@ModelAttribute("numbers") List&lt;Integer&gt; numbers 参数),两个模型属性方法都会被调用。但是,ParentModel.getNumbers() 总是在 ChildModel.getNumber() 之前调用。

请让我知道我是否遗漏了一些东西以使其完全正常工作,或者这是不可能的。

提前致谢!

编辑:

经过更多的实验,似乎不支持让模型属性依赖于其他模型属性。我将两个模型属性方法都放入 ParentModel 中,它充其量只能偶尔工作......这种偶尔的行为可能是由于反射返回方法的顺序。当 ParentModel.getNumbers() 在 ChildModel.getNumber() 之前调用时(理想的顺序),它可以正常工作。发现这一点后,我的后续问题是:有没有办法指定调用模型属性方法的顺序?

【问题讨论】:

    标签: java model-view-controller spring-mvc controller modelattribute


    【解决方案1】:

    Spring 抱怨它不能实例化一个接口列表,尝试将其声明为ArrayList(或LinkedList),它们都是接口列表的实现。

    【讨论】:

    • 感谢您的建议,但这样做会导致 ArrayOutOfBoundsException。 Spring 可能正在使用无参数构造函数来创建一个空列表,因为它仍在 parent.getItems() 之前调用 child.getItem()。
    【解决方案2】:

    我可能错误地使用了 Spring 模型属性。将属性添加到模型并重用它的一种方法是让第二个(依赖)方法将它们都添加到模型中,例如:

    public abstract class ParentModel {
    
        // no longer annotated as model attribute
        // adds the attribute to the model if it does not exist
        protected List<Integer> getNumbers(Model model) {
            List<Integer> numbers = (List<Integer>) model.asMap().get("numbers");
            if (numbers == null) {
                numbers = Arrays.asList(new Integer(1));
                model.addAttribute("numbers", numbers);
            }
            return numbers;
        }
    
    }
    
    @Controller
    public abstract class ChildModel extends ParentModel {
    
        @ModelAttribute("number")
        protected Integer getNumber(Model model) {
            return getNumbers(model).get(0);
        }
    
    }
    

    我也不确定这是否是设计 Spring MVC 继承模型填充控制器的好方法,但目前可行。

    【讨论】:

      猜你喜欢
      • 2014-09-21
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 2011-07-13
      • 1970-01-01
      • 2016-02-15
      相关资源
      最近更新 更多