Spring MVC 3.0 模型属性继承

发布于 2024-12-06 19:37:30 字数 1749 浏览 1 评论 0原文

我不确定这在 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]:指定的类是一个接口 在 org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101) 在 org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveModelAttribute(HandlerMethodInvoker.java:762) ...等等...

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

如果我缺少一些东西来使其完全正常工作,或者这是不可能的,请告诉我。

提前致谢!

编辑:

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

I'm not sure if this is possible in Spring MVC 3.0, but I'm trying to create an annotated Controller that extends another Controller and whose model attributes depend on a model attribute set by the parent. For example:

@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
    }

}

So far, I've been unable to get this to work - it throws the following exception:

Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [java.util.List]: Specified class is an interface] with root cause
org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [java.util.List]: Specified class is an interface
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveModelAttribute(HandlerMethodInvoker.java:762) ... etc ...

When the dependency on the attribute set by the parent is removed from ChildModel.getNumber() (by removing the @ModelAttribute("numbers") List<Integer> numbers parameter), both model attribute methods are called. However, ParentModel.getNumbers() is always called before ChildModel.getNumber().

Please let me know if I'm missing something to get this fully working or that this is just not possible.

Thanks in advance!

EDIT:

After some more experimentation, it seems that having model attributes depend on other model attributes is probably not supported. I put both model attribute methods into the ParentModel and it works sporadically at best... The sporadic behavior is likely due to the order in which the methods are returned by reflection. When ParentModel.getNumbers() is called before ChildModel.getNumber() (the desirable order), it works properly. Having discovered this, my follow-up question is: Is there a way to specify the order in which model attribute methods are called?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

违心° 2024-12-13 19:37:31

我可能错误地使用了 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 继承模型填充的好方法控制器也可以,但目前这是有效的。

I am probably using Spring model attributes incorrectly. One way to add an attribute to the model AND reuse it is to have the second (dependent) method add both of them to the model, e.g.:

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);
    }

}

I'm not sure if this is a good way to design Spring MVC inheriting model-populating controllers either, but for now this works.

星光不落少年眉 2024-12-13 19:37:30

Spring 抱怨因为它无法实例化一个 List,这是一个接口,尝试将其声明为 ArrayList( 或 LinkedList) 都是 List 接口的实现。

Spring is complaing becuase it cannot instantiate a List, which is an interface, try declaring it as ArrayList( or LinkedList) which are both implentations of the interface List.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文