知識庫 / Spring / Spring MVC RSS 訂閱

Spring MVC 中的 HandlerAdapter

Spring MVC
HongKong
4
02:42 PM · Dec 06 ,2025

1. 概述

本文將重點介紹 Spring 框架中可用的各種 Handler Adapter 實現。

2. 什麼是 HandlerAdapter?

HandlerAdapter 基本上是一個接口,它以一種靈活的方式在 Spring MVC 中促進 HTTP 請求的處理。

它與HandlerMapping 配合使用,HandlerMapping 將方法映射到特定的 URL。

DispatcherServlet 然後使用HandlerAdapter 調用該方法。 servlet 不直接調用該方法——它基本上充當其與 handler 對象之間的橋樑,從而實現鬆耦合設計。

下面是此接口中可用的各種方法:

public interface HandlerAdapter {
    boolean supports(Object handler);
    
    ModelAndView handle(
      HttpServletRequest request,
      HttpServletResponse response, 
      Object handler) throws Exception;
    
    long getLastModified(HttpServletRequest request, Object handler);
}

支持 API 用於檢查特定處理器的實例是否被支持。 在調用該接口的 handle() 方法之前,應首先調用此方法,以確保處理器實例是否被支持。

handle API 用於處理特定 HTTP 請求。 此方法負責通過將 HttpServletRequestHttpServletResponse 對象作為參數來調用處理器。 處理器執行應用程序邏輯並返回 ModelAndView 對象,然後由 DispatcherServlet 處理。

3. Maven 依賴

讓我們從需要添加到 pom.xml 中的 Maven 依賴開始:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.1.5</version>
</dependency>

最新版本的 spring-webmvc 構件可以在 這裏 找到。

4. HandlerAdapter 的類型

4.1. <em>SimpleControllerHandlerAdapter</em>

這是 Spring MVC 默認註冊的 handler 適配器。它處理實現 <em>Controller</em> 接口的類,並用於將請求轉發到控制器對象。

如果 Web 應用程序僅使用控制器,則我們不需要配置 <em>HandlerAdapter</em>,因為框架將此類作為處理請求的默認適配器。

讓我們定義一個簡單的控制器類,使用舊風格的控制器(實現 <em>Controller</em> 接口):

public class SimpleController implements Controller {
    @Override
    public ModelAndView handleRequest(
      HttpServletRequest request, 
      HttpServletResponse response) throws Exception {
        
        ModelAndView model = new ModelAndView("Greeting");
        model.addObject("message", "Dinesh Madhwal");
        return model;
    }
}

類似的 XML 配置:

<beans ...>
    <bean name="/greeting.html"
      class="com.baeldung.spring.controller.SimpleControllerHandlerAdapterExample"/>
    <bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

BeanNameUrlHandlerMapping 類是該處理器適配器的映射類。

**注意:** 如果在BeanFactory 中定義了自定義處理器適配器,則該適配器不會自動註冊。因此,我們需要在上下文中明確定義它。如果未定義它,並且我們已定義了自定義處理器適配器,則將會拋出異常,指出沒有指定處理器的適配器。

4.2. <em lang="en">SimpleServletHandlerAdapter</em>

此 Handler 適配器允許使用任何 <em lang="en">Servlet</em><em lang="en">DispatcherServlet</em> 協作,處理請求。它通過調用其 <em lang="en">service()</em> 方法,將請求從 <em lang="en">DispatcherServlet</em> 轉發到相應的 <em lang="en">Servlet</em> 類。

該適配器會自動處理實現 <em lang="en">Servlet</em> 接口的 Bean。默認情況下,它未註冊,因此需要在 <em lang="en">DispatcherServlet</em> 的配置文件中像任何其他普通 Bean 那樣進行註冊:

<bean name="simpleServletHandlerAdapter" 
  class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter" />

4.3. `AnnotationMethodHandlerAdapter</h3

此適配器類用於執行帶有 @RequestMapping 註解的方法。它用於根據 HTTP 方法和 HTTP 路徑映射方法。

此適配器的映射類是 DefaultAnnotationHandlerMapping

,它用於處理類型級別的 @RequestMapping註解,而 AnnotationMethodHandlerAdaptor 則用於處理方法級別的註解。

這兩個類在 DispatcherServlet初始化時已由框架註冊。但是,如果已定義其他適配器,則需要在配置文件中定義它們。

讓我們定義一個控制器類:

@Controller
public class AnnotationHandler {
    @RequestMapping("/annotedName")
    public ModelAndView getEmployeeName() {
        ModelAndView model = new ModelAndView("Greeting");        
        model.addObject("message", "Dinesh");       
        return model;  
    }  
}

@Controller 註解表明該類扮演着控制器的角色。

@RequestMapping 註解將getEmployeeName()方法映射到URL/name

根據應用程序是否使用基於Java的配置或基於XML的配置,有2種不同的配置方式。下面我們來看使用Java配置的第一種方式:

@ComponentScan("com.baeldung.spring.controller")
@Configuration
@EnableWebMvc
public class ApplicationConfiguration implements WebMvcConfigurer {
    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setPrefix("/WEB-INF/");
        bean.setSuffix(".jsp");
        return bean;
    }
}

如果應用程序使用 XML 配置,則配置此處理程序適配器在 Web 應用程序上下文中 XML 中有兩條不同的方法。讓我們先來看一下在文件 spring-servlet_AnnotationMethodHandlerAdapter.xml 中定義的第一個方法:

<beans ...>
    <context:component-scan base-package="com.baeldung.spring.controller" />
    <bean 
      class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
    <bean 
      class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
    <bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

<context:component-scan /> 標籤用於指定掃描 控制器類所在的包。

我們來看一下第二種方法:

<beans ...>
    <mvc:annotation-driven/>
    <context:component-scan base-package="com.baeldung.spring.controller" />
    <bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

<mvc:annotation-driven> 標籤將自動註冊這兩個類與 Spring MVC。 此適配器在 Spring 3.2 中已棄用,並在 Spring 3.1 中引入了新的RequestMappingHandlerAdapter 適配器。

4.4. RequestMappingHandlerAdapter

該適配器類在 Spring 3.1 中引入,取代了 Spring 3.2 中使用的 AnnotationMethodHandlerAdaptor 處理器適配器。

它與 RequestMappingHandlerMapping 類一起使用,該類 執行帶有 @RequestMapping 註解的方法。

RequestMappingHandlerMapping 用於維護請求 URI 到處理器的映射。獲得處理器後,DispatcherServlet 將請求分派到適當的處理器適配器,然後該適配器調用 handlerMethod()

在 Spring 3.1 之前,類型級別和方法級別的映射在兩個不同的階段進行處理。

第一階段是使用 DefaultAnnotationHandlerMapping 選擇控制器,第二階段是使用 AnnotationMethodHandlerAdapter 調用實際的方法。

從 Spring 3.1 版本開始,只有一個階段,它涉及識別控制器以及需要調用哪個方法來處理請求。

讓我們定義一個簡單的控制器類:

@Controller
public class RequestMappingHandler {
    
    @RequestMapping("/requestName")
    public ModelAndView getEmployeeName() {
        ModelAndView model = new ModelAndView("Greeting");        
        model.addObject("message", "Madhwal");        
        return model;  
    }  
}

可以通過以下兩種方式配置此適配器,具體取決於應用程序是否使用基於 Java 的配置或基於 XML 的配置。

讓我們首先看一下使用 Java 配置的第一個方法:

@ComponentScan("com.baeldung.spring.controller")
@Configuration
@EnableWebMvc
public class ServletConfig implements WebMvcConfigurer {
    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setPrefix("/WEB-INF/");
        bean.setSuffix(".jsp");
        return bean;
    }
}

如果應用程序使用 XML 配置,則配置此 HandlerAdapter 的方法有兩種,分別在 Web 應用程序上下文的 XML 文件中定義。下面我們來看一下在文件 spring-servlet_RequestMappingHandlerAdapter.xml 中定義的第一個方法:

<beans ...>
    <context:component-scan base-package="com.baeldung.spring.controller" />
    
    <bean 
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    
    <bean
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
    
    <bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

以下是第二個方法:

<beans ...>
    <mvc:annotation-driven />
    
    <context:component-scan base-package="com.baeldung.spring.controller" />
    
    <bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

此標籤將自動註冊這兩個類與 Spring MVC。

如果我們需要自定義 RequestMappingHandlerMapping,則需要從應用程序上下文 XML 中移除此標籤,並在應用程序上下文 XML 中手動進行配置。

4.5. HttpRequestHandlerAdapter

這個適配器用於處理 HttpRequest 的處理器。它實現了 HttpRequestHandler 接口,其中包含一個 handleRequest() 方法,用於處理請求並生成響應。

該方法的返回值類型為 void,它不生成像其他適配器那樣產生的 ModelAndView 返回類型。它主要用於生成二進制響應,並且不生成視圖進行渲染。

5. 運行應用程序

如果應用程序部署在 localhost 上,端口號為 8082,並且上下文根為 spring-mvc-handlers,則:

http://localhost:8082/spring-mvc-handlers/

6. 結論

在本文中,我們討論了 Spring 框架中可用的各種 HandlerAdapter 類型。

大多數開發者可能會堅持使用默認設置,但瞭解框架的靈活性對於超出基本功能的需求來説,絕對值得學習。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.