为什么请求命中控制器的方法而不是AbstractController的方法?

时间:2014-11-10 13:55:02

标签: oop spring-mvc

我是Spring MVC的新手,我知道一般我们设计一个控制器来实现“Controller”,但我写下面的代码,结果是“Hello World 1”而不是“Hello World 2”,那么任何人都可以告诉我为什么不“Hello World 2”?

那是:为什么请求调用我们实现的方法(Controller)而不是我们扩展(AbstractController)?

感谢。

package com.somesite.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.mvc.Controller;

public class HelloWorldController extends AbstractController implements Controller{

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg","Hello World 1");
    mv.setViewName("hello");
    return mv;
}
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg","Hello World 2");
    mv.setViewName("hello");
    return mv;
}

}

我的控制器配置如下:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
">

<!-- HandlerMapping -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

<!-- HandlerAdapter -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

<!-- ViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>

<!-- controller -->
<bean name="/hello" class="com.somesite.controller.HelloWorldController"/>

1 个答案:

答案 0 :(得分:0)

原因是API设计,如果你看到

控制器接口---&gt;

public interface Controller {
    org.springframework.web.servlet.ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws java.lang.Exception;
}

现在,如果您看到AbstractController抽象类,它实现了Controller接口本身,它包含 handleRequest 方法的实现。 最后声明如下。

return handleRequestInternal(request, response);



public abstract class AbstractController extends org.springframework.web.servlet.support.WebContentGenerator implements org.springframework.web.servlet.mvc.Controller {
    private boolean synchronizeOnSession;

    public AbstractController() { /* compiled code */ }

    public final void setSynchronizeOnSession(boolean synchronizeOnSession) { /* compiled code */ }

    public final boolean isSynchronizeOnSession() { /* compiled code */ }

    public org.springframework.web.servlet.ModelAndView handleRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.lang.Exception { /* compiled code */ }

    protected abstract org.springframework.web.servlet.ModelAndView handleRequestInternal(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws java.lang.Exception;
}

还有一件事你可以在那里看到另外一条评论。

模板方法。子类必须实现这一点。契约与handleRequest相同。(就在handleRequestInternal声明之上)。这意味着每个扩展AbstractController的控制器都必须提供实现 handleRequestInternal方法。

因此,为了执行请求,Spring MVC需要创建类的Object,进一步扩展 AbstractController 类,并提供 handleRequestInternal 方法的实现。

这里你扩展了 AbstractController Controller ,这是不正确的,因为你可以看到AbstractController本身实现了Controller接口。

因此,如果你想执行你的控制器的handleRequest()方法,我认为你将不得不实现只有Controller接口不扩展AbstractController类