1. 項目結構總結
這個Spring MVC項目采用Maven管理,遵循標準的Web項目結構。以下是詳細的文件級別結構:
核心目錄結構
springmvc_helloword/
├── .idea/ # IDEA項目配置目錄
│ ├── artifacts/ # 項目打包配置
│ └── libraries/ # 項目依賴庫配置
├── src/ # 源代碼目錄
│ ├── main/ # 主源碼
│ │ ├── java/com/zhang/controller/ # 控制器包
│ │ │ ├── HelloController.java # 主要控制器
│ │ │ └── PathVariableController.java # 路徑變量控制器
│ │ └── resources/ # 資源文件目錄
│ │ └── springmvc.xml # Spring MVC核心配置文件
│ └── test/ # 測試代碼目錄
├── web/ # Web資源目錄
│ ├── WEB-INF/ # Web應用配置目錄
│ │ ├── page/ # 視圖頁面目錄
│ │ │ └── hello.jsp # 主視圖頁面
│ │ └── web.xml # Web應用配置文件
│ ├── heihei.html # 靜態HTML頁面
│ └── index.jsp # 首頁JSP
├── target/ # 編譯構建輸出目錄
│ ├── classes/ # 編譯后的class文件
│ └── springmvc_helloword-1.0-SNAPSHOT.war # 打包后的War文件
├── pom.xml # Maven項目配置文件
└── springmvc_helloword.iml # IDEA模塊配置文件
2. Demo練習內容詳解
這個Spring MVC演示項目主要練習了以下核心功能和知識點:
2.1 Spring MVC基本架構和請求處理流程
- 演示了完整的Spring MVC請求處理流程:從瀏覽器請求 → DispatcherServlet前端控制器 → Controller控制器處理 → 視圖解析 → 響應頁面
- 配置了核心組件:DispatcherServlet、Controller、ViewResolver
2.2 控制器(Controller)的配置與使用
- 練習了基于注解的控制器開發(@Controller、@RequestMapping)
- 實現了兩個不同的控制器:HelloController和PathVariableController
- 展示了控制器方法如何返回視圖名稱
2.3 請求映射(Request Mapping)的多種配置方式
- 基礎URL映射:通過@RequestMapping注解映射請求路徑
- 類級和方法級映射組合:在類和方法上同時使用@RequestMapping,形成組合路徑
- 請求頭限制:通過headers參數限制特定請求頭的請求
- 請求方式限制:支持配置GET/POST等請求方法
- 模糊匹配:使用通配符*進行路徑模糊匹配
- 參數限制:通過params參數限制請求必須包含特定參數
2.4 路徑變量(PathVariable)的使用
- 演示了@PathVariable注解獲取URL路徑中的變量值
- 展示了如何將路徑變量綁定到方法參數
- 實現了RESTful風格的URL設計
2.5 視圖解析器的配置與使用
- 配置了InternalResourceViewResolver視圖解析器
- 設置了前綴(prefix)和后綴(suffix),實現視圖名稱到物理路徑的映射
- 練習了控制器向視圖傳遞數據(使用Map傳遞屬性)
2.6 靜態資源處理
- 配置了DefaultServlet處理靜態HTML資源
- 演示了如何避免DispatcherServlet攔截靜態資源的問題
- 添加了mvc:default-servlet-handler和mvc:annotation-driven配置解決靜態資源訪問
2.7 Spring MVC配置方式
- 練習了XML配置方式:在springmvc.xml中配置組件掃描、視圖解析器等
- 練習了注解配置方式:使用@ComponentScan、@Controller等注解
- 解決了XML配置和注解配置沖突的問題
2.8 Maven項目配置與打包
- 配置了Spring相關依賴(spring-context、spring-web、spring-webmvc)
- 設置了打包類型為war包
- 配置了maven-war-plugin插件自定義Web資源目錄
2.9 JSP視圖開發
- 創建了JSP頁面并使用EL表達式(${hello})獲取控制器傳遞的數據
- 實現了簡單的表單提交功能
這個項目作為Spring MVC的入門練習,涵蓋了MVC架構的核心概念和Spring MVC框架的基礎功能,幫助理解Web應用的分層設計和請求處理機制。
訪問: http://localhost:8083/testPathVariable/456/mary
http://localhost:8083/
代碼
controller層
package com.zhang.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import java.util.Map;/**** springmvc處理過程* 1、瀏覽器要發送一個請求 http://localhost:8080/springmvc_helloworld_war_exploded/hello* 2、首先交給tomcat容器* 3、在web.xml文件中配置了DispatcherServlet的類,所以此時會由當前的DispatcherServlet來接受請求* 4、接受到請求之后找到對應的Controller,去Controller中尋找@RequestMapping注解標識的方法* 5、找到匹配的方法之后,執行方法的邏輯* 6、處理完成之后需要返回一個前端頁面的名稱,* 7、有視圖處理器來根據名稱映射到對應的jsp頁面的路徑* 8、DispatcherServlet拿到對應的路徑地址之后返回給瀏覽器**/
@Controller
@RequestMapping("/hello")
public class HelloController{/** @RequestMapping表示用來匹配當前方法要處理的請求,其中/可以寫也可以不寫,一般推薦協商** @RequestMapping可以添加在類上,也可以添加在方法上* 方法:http://localhost:8080/springmvc_helloworld_war_exploded/hello* 類:http://localhost:8080/springmvc_helloworld_war_exploded/hello/hello* 當添加在類上的時候表示給所有的當前類的方法錢添加一個訪問路徑* 什么時候需要在類上添加此注解?* 當包含多個Controller,通過在不同的Controller中包含同名的請求的時候,需要添加** @RequestMapping配置的參數* value:表示要匹配的請求* method:表示請求的方式,post get* params:表示要求請求中必須要包含的參數* 必須要包含username的屬性值* @RequestMapping( value = "/hello",params = {"username"})* 不能包含的參數名稱@RequestMapping( value = "/hello",params = {"!username"})必須要包含username,age兩個屬性值,并且username的值為zhangsan@RequestMapping( value = "/hello",params = {"username=zhangsan","age"})* headers:表示限制請求頭中的相關屬性值,用來做請求的限制* produces:限制請求中的Content-Type* consumers:限制響應中的Content-Type*** @RequestMapping可以進行模糊匹配* ?:替代任意一個字符* *:替代多個字符* **:替代多層路徑* 如果能匹配到多個請求,那么優先是精準匹配,其次是模糊匹配* */@RequestMapping( value = "/hello",headers = {"User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36"})public String hello(Map<String,String> map){map.put("hello","hello,Springmvc");return "hello";}@RequestMapping( value = "/hello*")public String hello2(Map<String,String> map){map.put("hello","hello,heihei");return "hello";}
}package com.zhang.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.view.InternalResourceViewResolver;@Controller
public class PathVariableController {/*** @PathVariable可以獲取請求路徑中的值* 在路徑中要使用{變量名稱}做標識* 在方法參數中可以添加@PathVariable做識別,如果路徑中的名稱跟參數的名稱不一致的時候,可以添加路徑中的變量名稱* 推薦添加* @param id* @param name* @return*/@RequestMapping("/testPathVariable/{id}/{name}")public String testPathVariable(@PathVariable("id") Integer id ,@PathVariable("name") String name){//request.getParameter("name")System.out.println(id);System.out.println(name);return "hello";}
}
配置文件
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.zhang"></context:component-scan>
<!--加個注解處理html--><mvc:default-servlet-handler></mvc:default-servlet-handler><!-- 添加注解驅動配置,這會注冊必要的處理器適配器和處理器映射 --><mvc:annotation-driven/><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/page/"></property><property name="suffix" value=".jsp"></property></bean><!-- 跟注解沖突了, 二者留其一 -->
<!-- <bean id="/hello" class="com.zhang.controller.HelloController"></bean>--></beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--配置前端控制器DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--設置初始化參數,指定默認的springmvc的配置文件可以選擇將springmvc的配置文件添加到/WEB-INF/的目錄下。默認是從此目錄查找配置文件但是需要注意的是,配置文件的名稱必須是 (DispatcherServlet的servlet-name)-servlet.xml--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!--添加前端控制器對應的mapping映射:映射所有的請求,因此最好寫成/ /*(區別?)/:用來匹配所有請求,但是/不會攔截jsp頁面/*:用來匹配所有的請求,會攔截jsp頁面此時如果創建一個html頁面之后,是無法請求到的,原因是:每個項目的web.xml文件會繼承tomcat下的web.xml文件,而在tomcat-web.xml文件中包含了一個DefaultServlet的處理類用來處理靜態資源,但是我們在編寫自己的DispatcherServlet的時候使用了/的方式,此方式覆蓋了父web,xml對于靜態資源的處理所以此時所有的靜態資源的訪問也需要由DispatcherServlet來進行處理,但是我們并沒有設置對應的Controller,所以報404為什么jsp能處理呢?在父web.xml文件中包含了一個JSPServlet的處理類,會有tomcat進行處理,而不是我們定義的DispatcherServlet--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><servlet><servlet-name>default</servlet-name><servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class></servlet><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.html</url-pattern></servlet-mapping>
</web-app>
前端頁面
<!-- heihei.html --><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
hello,html
</body>
</html><!-- index.jsp-->
<%--Created by IntelliJ IDEA.User: rootDate: 2020/3/14Time: 15:44To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>$Title$</title>
</head>
<%pageContext.setAttribute("ctp",request.getContextPath());
%>
<body>
<form action="${ctp}/hello/hello" method="post"><input type="text" name="username"><br><input type="submit" value="提交">
</form>
</body>
</html><!-- /WEB-INF/page/heihei.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
heihei.html
heihei.html
heihei.html
</body>
</html><!-- /WEB-INF/page/hello.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>hello.html
</body>
</html><!-- /WEB-INF/page/hello.jsp-->
<html>
<head><title>Title</title>
</head>
<body>
謝
${hello}
</body>
</html>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zhang</groupId><artifactId>springmvc_helloword</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging>
<dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.3.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-web --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.2.3.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.3.RELEASE</version></dependency><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-catalina</artifactId><version>8.0.36</version></dependency>
<!-- <!– Servlet依賴–>-->
<!-- <dependency>-->
<!-- <groupId>javax.servlet</groupId>-->
<!-- <artifactId>javax.servlet-api</artifactId>-->
<!-- <version>3.1.0</version>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!-- <!– JSP依賴–>-->
<!-- <dependency>-->
<!-- <groupId>javax.servlet.jsp</groupId>-->
<!-- <artifactId>javax.servlet.jsp-api</artifactId>-->
<!-- <version>2.3.3</version>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!-- <!– jstl表達式的依賴–>-->
<!-- <dependency>-->
<!-- <groupId>javax.servlet</groupId>-->
<!-- <artifactId>jstl</artifactId>-->
<!-- <version>1.2</version>-->
<!-- </dependency>-->
<!-- <!– standar標簽庫–>-->
<!-- <dependency>-->
<!-- <groupId>taglibs</groupId>-->
<!-- <artifactId>standard</artifactId>-->
<!-- <version>1.1.2</version>-->
<!-- </dependency>-->
</dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.3.2</version><configuration><webResources><resource><directory>web</directory></resource></webResources></configuration></plugin></plugins></build>
</project>