SpringMVC 是一種基于 ?的實現 MVC 設計模式的請求驅動類型的輕量級 Web 框架,屬于 Spring FrameWork 的后續產品,已經融合在 Spring Web Flow 中。
First:SpringMVC-01-SpringMVC 概述
SpringMVC 是 Spring 框架的一個模塊,用于構建 Web 應用程序。它遵循 MVC (Model-View-Controller) 架構模式,將請求處理、業務邏輯和視圖展示分離,使代碼結構清晰,易于維護和測試。
SpringMVC 的主要特點:
-輕量級,非侵入式
-強大的請求映射機制
-支持多種視圖技術
-強大的異常處理機制
-支持文件上傳
-國際化和本地化支持
-支持 RESTful 風格的 URL
SpringMVC-02-SpringMVC 入門案例
下面是一個簡單的 SpringMVC 入門案例,展示了如何創建一個基本的 Web 應用。
1. 添加 Maven 依賴
這些依賴是構建 SpringMVC 應用的基礎:
xml:
<dependencies>
????<!-- Spring MVC核心庫 -->
????<dependency>
????????<groupId>org.springframework</groupId>
????????<artifactId>spring-webmvc</artifactId>
????????<version>5.3.18</version>
????</dependency>
????
????<!-- Servlet API (由容器提供,無需打包) -->
????<dependency>
????????<groupId>x.servlet</groupId>
????????<artifactId>x.servlet-api</artifactId>
????????<version>4.0.1</version>
????????<scope>provided</scope>
????</dependency>
????
????<!-- JSP支持 (用于視圖渲染) -->
????<dependency>
????????<groupId>x.servlet.jsp</groupId>
????????<artifactId>x.servlet.jsp-api</artifactId>
????????<version>2.3.3</version>
????????<scope>provided</scope>
</dependency>
</dependencies>
關鍵依賴說明:
spring-webmvc:SpringMVC 框架的核心庫
x.servlet-api:Servlet 容器接口
x.servlet.jsp-api:JSP 頁面支持
2. Servlet 初始化類(AppInitializer)
這個類替代了傳統的 web.xml 配置,用于注冊 DispatcherServlet:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
????@Override
????protected Class<?>[] getRootConfigClasses() {
????????return null; // 根應用上下文配置(通常包含服務層和數據訪問層)
????}
????@Override
????protected Class<?>[] getServletConfigClasses() {
????????return new Class<?>[] { WebConfig.class }; // Web層配置
????}
????@Override
????protected String[] getServletMappings() {
????????return new String[] { "/" }; // 映射所有請求到DispatcherServlet
}
}
核心作用:
自動注冊 Spring MVC 的前端控制器DispatcherServlet
指定配置類位置
映射請求路徑
3. Spring 配置類(WebConfig)
配置 SpringMVC 的核心組件:
@Configuration
@EnableWebMvc // 啟用Spring MVC注解支持
@ComponentScan(basePackages = "com.example.controller") // 掃描控制器
public class WebConfig {
????@Bean
????public ViewResolver viewResolver() {
????????InternalResourceViewResolver resolver = new InternalResourceViewResolver();
????????resolver.setPrefix("/WEB-INF/views/"); // JSP文件位置
????????resolver.setSuffix(".jsp"); // 文件后綴
????????return resolver;
}
}
關鍵配置項:
@EnableWebMvc:啟用 Spring MVC 注解驅動
ComponentScan:掃描@Controller注解的類
ViewResolver:配置視圖解析器,將邏輯視圖名映射到物理 JSP 文件
4. 控制器(HelloController)
處理 HTTP 請求并返回視圖:
@Controller
@RequestMapping("/hello")
public class HelloController {
????@RequestMapping(method = RequestMethod.GET)
????public String sayHello(Model model) {
????????model.addAttribute("message", "Hello Spring MVC!");
????????return "hello"; // 邏輯視圖名
}
}
核心注解:
@Controller:聲明這是一個 Spring MVC 控制器
@RequestMapping:映射請求路徑和 HTTP 方法
Model:用于傳遞數據到視圖
5. JSP 視圖(hello.jsp)
渲染最終響應頁面:
jsp
<!DOCTYPE html>
<html>
<head>
????<title>Hello Spring MVC</title>
</head>
<body>
????<h1>${message}</h1> <!-- 接收控制器傳遞的數據 -->
</body>
</html>
關鍵技術點:
EL 表達式 (${message}):用于獲取模型數據
視圖位置:/WEB-INF/views/hello.jsp(由 ViewResolver 配置決定)
入門案例工作流程解析
當訪問http://localhost:8080/hello時:
請求到達DispatcherServlet(由 AppInitializer 注冊)
DispatcherServlet 通過 HandlerMapping 找到對應的HelloController
執行sayHello()方法,將數據存入 Model
返回邏輯視圖名 "hello"
ViewResolver 將 "hello" 解析為 / WEB-INF/views/hello.jsp
JSP 頁面渲染并返回響應
SpringMVC-03 - 入門案例工作流程解析
SpringMVC 的工作流程可以概括為以下幾個步驟:
客戶端發送請求到 DispatcherServlet
DispatcherServlet 接收請求并查詢 HandlerMapping?找到處理該請求的 Controller
DispatcherServlet 調用 HandlerAdapter 來執行 Controller
Controller 處理請求并返回一個 ModelAndView 對象給 HandlerAdapter
HandlerAdapter 將 ModelAndView 返回給 DispatcherServlet
DispatcherServlet 查詢 ViewResolver 找到與 ModelAndView 中邏輯視圖名對應的實際視圖
DispatcherServlet 將模型數據傳遞給視圖
視圖渲染結果返回給客戶端
SpringMVC-04-bean 加載控制
在 SpringMVC 中,有兩種類型的 ApplicationContext:
root 上下文 (Root ApplicationContext):包含應用的業務邏輯、數據訪問等 Bean
Servlet 上下文 (Servlet ApplicationContext):包含控制器、視圖解析器等 Web 相關 Bean
可以通過配置來控制哪些 Bean 被加載到哪個上下文:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
????@Override
????protected Class<?>[] getRootConfigClasses() {
????????return new Class<?>[] { RootConfig.class };
????}
????@Override
????protected Class<?>[] getServletConfigClasses() {
????????return new Class<?>[] { WebConfig.class };
????}
????@Override
????protected String[] getServletMappings() {
????????return new String[] { "/" };
}
}
@Configuration
@ComponentScan(basePackages = "com.example.service, com.example.repository")
public class RootConfig {
// 根上下文配置
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.controller")
public class WebConfig {
// Servlet上下文配置
}
SpringMVC-05-PostMan 工具介紹
Postman 是一個用于測試 API 的工具,它可以發送各種 HTTP 請求 (GET、POST、PUT、DELETE 等),設置請求頭、請求參數、請求體等,并查看響應結果。
使用 Postman 測試 SpringMVC API 的步驟:
打開 Postman,創建一個新的請求
選擇請求方法 (GET、POST 等)
輸入請求 URL
設置請求頭 (如 Content-Type)
設置請求參數或請求體
點擊發送按鈕查看響應結果
SpringMVC-06 - 設置請求映射路徑
在 SpringMVC 中,可以使用 @RequestMapping 注解來設置請求映射路徑。該注解可以應用于類和方法上。
@Controller
@RequestMapping("/products")
public class ProductController {
????// 處理GET請求 /products
????@RequestMapping(method = RequestMethod.GET)
????public String listProducts(Model model) {
????????// 獲取產品列表
????????return "products/list";
????}
????// 處理GET請求 /products/{id}
????@RequestMapping(value = "/{id}", method = RequestMethod.GET)
//@GetMappeing (value = "{id}")
????public String getProduct(@PathVariable("id") Long id, Model model) {
????????// 獲取單個產品
????????return "products/detail";
????}
????// 處理POST請求 /products
????@RequestMapping(method = RequestMethod.POST)
????public String addProduct(@ModelAttribute Product product) {
????????// 添加產品
????????return "redirect:/products";
}
}
SpringMVC-07-get 請求與 post 請求發送普通參數
一、GET 請求參數處理
1. 請求結構與參數傳遞
GET 請求將參數附加在 URL 的查詢字符串中,格式為?參數名1=值1&參數名2=值2。例如:
http://localhost:8080/search?keyword=手機
瀏覽器發送的完整 HTTP 請求示例:
http:
GET /search?keyword=%E6%89%8B%E6%9C%BA HTTP/1.1
Host: localhost:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: keep-alive
2. @RequestParam 注解詳解
@Controller
@RequestMapping("/search")
public class SearchController {
????// 基礎用法
????@GetMapping
????public String search(@RequestParam("keyword") String keyword, Model model) {
????????// 處理搜索邏輯
????????List<Product> results = productService.search(keyword);
????????model.addAttribute("results", results);
????????return "search/results";
????}
????// 可選參數與默認值
????@GetMapping("/advanced")
????public String advancedSearch(
????????@RequestParam(value = "keyword", required = false) String keyword, ?// 可選參數
????????@RequestParam(value = "category", defaultValue = "all") String category, ?// 默認值
????????@RequestParam(value = "page", defaultValue = "1") int page,
????????@RequestParam(value = "size", defaultValue = "10") int size
????) {
????????// 處理高級搜索
????????return "search/advanced";
????}
????// 綁定多個同名參數到List
????@GetMapping("/filter")
????public String filterProducts(@RequestParam("category") List<String> categories) {
????????// URL: /filter?category=手機&category=電腦
????????return "products/filter";
????}}
3. 前端表單示例(GET 請求)
html
預覽
<form action="/search" method="get">
????<input type="text" name="keyword" placeholder="搜索關鍵詞">
????<select name="category">
????????<option value="all">全部</option>
????????<option value="phone">手機</option>
????????<option value="computer">電腦</option>
????</select>
<button type="submit">搜索</button>
</form>
二、POST 請求參數處理
1. 請求結構與參數傳遞
POST 請求將參數封裝在請求體中,需要指定Content-Type頭。常見的Content-Type有:
application/x-www-form-urlencoded(默認)
multipart/form-data(文件上傳)
application/json(JSON 數據)
瀏覽器發送的完整 HTTP 請求示例:
http:
POST /user/register HTTP/1.1Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
username=test&password=123456&email=test%40example.com
2. @RequestParam 處理簡單參數
@Controller
@RequestMapping("/user")
public class UserController {
????@PostMapping("/login")
????public String login(
????????@RequestParam("username") String username,
????????@RequestParam("password") String password,
????????Model model
????) {
????????User user = userService.validateUser(username, password);
????????if (user != null) {
????????????return?"redirect:/home";
????????} else {
????????????model.addAttribute("error", "用戶名或密碼錯誤");
????????????return "login";
????????}
}
}
3. @ModelAttribute 處理對象參數
// User類public class User {
????private String username;
????private String password;
????private String email;
????private Integer age;
// getters/setters
}
@Controller
@RequestMapping("/user")
public class UserController {
????@PostMapping("/register")
????public String register(@ModelAttribute User user) {//表單->User對象
????????// 自動將表單參數綁定到User對象
????????userService.register(user);
????????return "redirect:/user/login";
}
}
4. 前端表單示例(POST 請求)
html
<form action="/user/register" method="post">
????用戶名: <input type="text" name="username"><br>
????密碼: <input type="password" name="password"><br>
????郵箱: <input type="email" name="email"><br>
????年齡: <input type="number" name="age"><br>
<input type="submit" value="注冊">
</form>
SpringMVC-08-5 種類型參數傳遞
SpringMVC 支持多種方式的參數傳遞:
路徑變量 (Path Variable)
@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
public String getUser(@PathVariable("id") Long id, Model model) {
// 處理邏輯
}
請求參數 (Request Parameter)
@RequestMapping(value = "/search", method = RequestMethod.GET)
public String search(@RequestParam("keyword") String keyword, Model model) {
// 處理邏輯
}
請求頭 (Request Header)
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseEntity<byte[]> download(@RequestHeader("User-Agent") String userAgent) {
// 處理邏輯
}
Cookie 值
@RequestMapping(value = "/profile", method = RequestMethod.GET)
public String profile(@CookieValue("JSESSIONID") String sessionId, Model model) {
????// 處理邏輯}
請求體 (用于 POST/PUT 請求)
@RequestMapping(value = "/users", method = RequestMethod.POST)
public ResponseEntity<User> createUser(@RequestBody User user) {
// 處理邏輯
}
SpringMVC-09-json 數據傳遞參數
在 RESTful API 中,通常使用 JSON 格式傳遞數據。可以使用 @RequestBody 和 @ResponseBody 注解來處理 JSON 數據。
首先需要添加 Jackson 依賴:
xml
<dependency>
????<groupId>com.fasterxml.jackson.core</groupId>
????<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
控制器示例:
@RestController
@RequestMapping("/api/users")
public class UserRestController {
????@PostMapping
????public User createUser(@RequestBody User user) {//JSON->對象
????????// 創建用戶
????????return userService.save(user);
????}
????@GetMapping("/{id}")
????public User getUser(@PathVariable Long id) {
????????// 獲取用戶
????????return userService.findById(id);
}
}
SpringMVC-10 - 日期型參數傳遞
SpringMVC 默認情況下可能無法正確解析日期參數,需要進行額外配置。
使用 @DateTimeFormat 注解:
@RequestMapping(value = "/events", method = RequestMethod.GET)
public String getEvents(@RequestParam("date")
@DateTimeFormat(pattern = "yyyy-MM-dd") //格式
LocalDate date, Model model) {
// 處理邏輯
}
全局日期格式化配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
????@Override
????public void addFormatters(FormatterRegistry registry) {
????????DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
????????registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
????????registrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
????????registrar.registerFormatters(registry);
}
}