首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring MVC 入門核心原理與註解驅動開發實戰

     編輯:Java 綜合教學

從 DispatcherServlet 到 @RequestMapping:Spring MVC 請求處理全流程解析

Spring MVC 是 Spring 框架內置的 Web 模塊,基於前端控制器模式,將請求分發、模型綁定、視圖渲染等職責解耦。本文從核心組件架構、註解配置、數據綁定、視圖解析、RESTful 支持五個維度,構建完整知識體系。

一、 核心架構:九大組件協作流程

請求處理鏈路
用戶請求 HTTP Request
        │
        ▼
┌───────────────────────┐
│  DispatcherServlet    │  前端控制器:統一入口、協調調度
└───────────┬───────────┘
        │
        ▼
┌───────────────────────┐
│  HandlerMapping       │  處理器映射器:URL → Handler (Controller 方法)
│  (RequestMappingHandlerMapping)           │
└───────────┬───────────┘
        │
        ▼
┌───────────────────────┐
│  HandlerAdapter       │  處理器適配器:統一調用接口,支持多種 Handler 類型
│  (RequestMappingHandlerAdapter)           │
└───────────┬───────────┘
        │
        ▼
┌───────────────────────┐
│  Controller (Handler) │  業務處理器:@Controller / @RestController 方法
└───────────┬───────────┘
        │
        ▼
┌───────────────────────┐
│  ModelAndView /       │  模型數據 + 邏輯視圖名
│  @ResponseBody        │
└───────────┬───────────┘
        │
        ▼
┌───────────────────────┐
│  ViewResolver         │  視圖解析器:邏輯視圖名 → View 實例 (JSP/Thymeleaf/FreeMarker)
│  (InternalResourceViewResolver)         │
└───────────┬───────────┘
        │
        ▼
┌───────────────────────┐
│  View                 │  視圖渲染:模板引擎輸出 HTML/JSON/XML
└───────────┬───────────┘
        │
        ▼
用戶響應 HTTP Response
  

二、 快速啟動:註解驅動配置 (Spring 3.1+)

1. web.xml 配置 DispatcherServlet

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value> <!-- 指定配置文件 -->
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern> <!-- 攔截所有請求,靜態資源需額外配置 -->
</servlet-mapping>

url-pattern 三種模式對比:

模式示例特點建議
*.do / *.action/user/login.do傳統風格,易區分靜態資源老項目維護
//user/loginRESTful 風格,攔截所有,**需配置靜態資源處理**新項目首選
/*/user/login, /page.jsp連 JSP 也攔截,導致視圖解析失敗 (無限循環/404)嚴禁使用

2. spring-mvc.xml 核心配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="https://www.springframework.org/schema/context"
       xmlns:mvc="https://www.springframework.org/schema/mvc"
       xsi:schemaLocation="...>

    <!-- 1. 掃描 Controller (掃描不到則無法映射) -->
    <context:component-scan base-package="com.test.controller" />

    <!-- 2. 註解驅動:自動註冊 RequestMappingHandlerMapping/Adapter、參數綁定、格式化、驗證、消息轉換器 -->
    <mvc:annotation-driven />

    <!-- 3. 視圖解析器 (JSP 示例) -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 4. 靜態資源處理 (配合 url-pattern: /) -->
    <mvc:resources mapping="/static/**" location="/static/" />
    <mvc:default-servlet-handler />

</beans>

三、 Controller 開發核心註解詳解

1. @RequestMapping 及變體

註解HTTP 方法說明
@RequestMappingALL通用映射,可窄化 method/params/headers/consumes/produces
@GetMappingGET組合註解,等同 @RequestMapping(method=GET)
@PostMappingPOST表單提交、數據創建
@PutMappingPUT全量更新
@PatchMappingPATCH部分更新
@DeleteMappingDELETE刪除資源

2. 參數綁定註解

@Controller
@RequestMapping("/user")  // 類級別:基礎路徑
public class UserController {

    // 1. 路徑變量
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) { ... }

    // 2. 請求參數 (自動類型轉換、必填校驗、默認值)
    @GetMapping("/list")
    public List list(
        @RequestParam(value = "page", defaultValue = "1") int page,
        @RequestParam(value = "size", required = false) Integer size
    ) { ... }

    // 3. 請求頭
    @GetMapping("/header")
    public String header(@RequestHeader("User-Agent") String ua) { ... }

    // 4. Cookie
    @GetMapping("/cookie")
    public String cookie(@CookieValue("JSESSIONID") String sessionId) { ... }

    // 5. 請求體 (JSON/XML → 對象) - 核心:@RequestBody + HttpMessageConverter
    @PostMapping("/save")
    public User save(@RequestBody @Valid User user, BindingResult result) { ... }

    // 6. 表單對象綁定 (無註解,屬性名匹配)
    @PostMapping("/form")
    public String form(UserForm form) { ... } // 自動綁定 request parameters

    // 7. 原生 Servlet API 直接注入
    @GetMapping("/native")
    public void nativeApi(HttpServletRequest req, HttpServletResponse resp, HttpSession session) { ... }
}

3. 返回值類型與視圖解析策略

返回類型處理邏輯適用場景
ModelAndView攜帶模型數據 + 邏輯視圖名傳統 MVC,需渲染頁面
String視為邏輯視圖名 → ViewResolver 解析簡單頁面跳轉
void自行通過 response 輸出 / 轉發 / 重定向文件下載、流式響應、手動控制
@ResponseBody + 對象對象 → HttpMessageConverter → JSON/XML 直接寫入響應體REST API、AJAX
ResponseEntity<T>完全控制:狀態碼、頭部、體需自定義 HTTP 狀態碼
@ModelAttribute模型屬性,可用於頁面渲染表單回顯

4. 重定向與轉發語法

@GetMapping("/redirect")
public String redirect() {
    return "redirect:/user/list"; // 瀏覽器重新發起 GET 請求,地址欄變化
}

@GetMapping("/forward")
public String forward() {
    return "forward:/user/list"; // 服務端內部轉發,地址欄不變,共享 request 域
}

四、 核心進階:HttpMessageConverter 與 JSON 支持

@RequestBody / @ResponseBody 背後依賴 RequestMappingHandlerAdapter 裝配的 HttpMessageConverter<?> 鏈:

<mvc:annotation-driven>
    <mvc:message-converters>
        <!-- 順序很重要:優先匹配 -->
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                    <!-- 配置序列化特性 -->
                    <property name="serializationInclusion" value="NON_NULL" />
                    <property name="dateFormat">
                        <bean class="java.text.SimpleDateFormat">
                            <constructor-arg value="yyyy-MM-dd HH:mm:ss" />
                        </bean>
                    </property>
                </bean>
            </property>
        </bean>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list><value>text/plain;charset=UTF-8</value></list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

五、 常見問題與最佳實踐

  1. 400 Bad Request (Required String parameter 'xxx' is not present):檢查前端參數名與 @RequestParam(value="xxx") 是否一致,或設置 required=false。
  2. 415 Unsupported Media Type:請求頭 Content-Type 與消息轉換器支持類型不匹配(如發 JSON 卻無 Jackson 轉換器)。
  3. 循環引用導致 JSON 序列化無限遞歸:實體類加 @JsonIgnore / @JsonBackReference / 配置 ObjectMapper 禁用循環引用檢測。
  4. 靜態資源 404:url-pattern: / 必須配置 <mvc:resources> 和 <mvc:default-servlet-handler/>。
  5. 路徑變量包含點號被截斷:/user/{email:.+} 使用正則捕獲完整路徑段。
  6. 矩陣變量:/cars;color=red;year=2020 需啟用 enableMatrixVariables=true (WebMvcConfigurer)。

六、 從 XML 到 Java Config 現代化配置 (Spring 3.2+)

@Configuration
@EnableWebMvc              // 等同 <mvc:annotation-driven/>
@ComponentScan("com.test.controller")
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/jsp/", ".jsp");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
    }

    @Override
    public void configureMessageConverters(List> converters) {
        // 自定義 Jackson 配置
        converters.add(new MappingJackson2HttpMessageConverter(customObjectMapper()));
    }
    
    // 文件上傳解析器
    @Bean
    public MultipartResolver multipartResolver() {
        StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
        return resolver;
    }
}

Spring MVC 的設計精髓在於開放封閉原則:核心調度流程固化,擴展點(HandlerMapping、HandlerAdapter、HandlerExceptionResolver、ViewResolver、HttpMessageConverter)全面接口化。掌握註解驅動背後的組件裝配機制,能讓你在遇到疑難雜症時快速定位到具體擴展點進行定制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved