0

我不确定在Spring MVC 3.0中是否可以这样做,但我试图创建一个注释的Controller来扩展另一个Controller,并且其模型属性依赖于由父级设置的模型属性。例如: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]:指定的类是具有根本原因的接口] org.springframework.beans.BeanInstantiationException:无法实例化bean类[java。 util.List]:指定的类是一个接口 at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveModelAttribute(HandlerMethodInvoker.java: 762)...等...

当在由父设置属性的依赖性被从ChildModel.getNumber()(通过去除@ModelAttribute("numbers") List<Integer> numbers参数去除),这两个模型属性方法被调用。但是,ParentModel.getNumbers()始终在ChildModel.getNumber()之前调用。

请让我知道如果我失去了一些东西,让这个完全正常工作,或者这是不可能的。

在此先感谢!

编辑:

后一些更多的试验,似乎为模型的属性依赖于其他模型属性可能是不支持。我将两个模型属性方法都放到了ParentModel中,并且它最多只能偶尔运行......零星的行为可能是由于反射返回方法的顺序。在ChildModel.getNumber()(需要的顺序)之前调用ParentModel.getNumbers()时,它可以正常工作。发现了这个后,我的后续问题是:有没有一种方法来指定调用模型属性方法的顺序?

回答

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也会继承模型填充控制器,但现在这个工作。

3

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

+1

感谢您的建议,但是这样做会导致ArrayOutOfBoundsException。 Spring可能使用no-args构造函数来创建一个空列表,因为它仍然在parent.getItems()之前调用child.getItem()。 – andy