理解MVC架构与SpringMVC核心概念
SpringMVC 是 Spring 框架的一部分,是基于 MVC 设计模式的 Web 框架,用于构建灵活、松耦合的 Web 应用程序。
MVC 模式实现了关注点分离,使得代码更易维护、测试和扩展。视图层、业务逻辑层、数据访问层各司其职。
1. 用户发送请求 → DispatcherServlet
2. DispatcherServlet → HandlerMapping(查找 Controller)
3. HandlerMapping → DispatcherServlet(返回 Handler)
4. DispatcherServlet → HandlerAdapter(执行 Handler)
5. HandlerAdapter → Controller(调用业务方法)
6. Controller → HandlerAdapter(返回 ModelAndView)
7. HandlerAdapter → DispatcherServlet
8. DispatcherServlet → ViewResolver(解析视图)
9. ViewResolver → DispatcherServlet(返回 View)
10. DispatcherServlet → View(渲染)
11. View → 用户(返回响应)<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSP API -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies><!-- web.xml -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/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><!-- spring-mvc.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context">
<!-- 启用注解驱动 -->
<mvc:annotation-driven/>
<!-- 扫描控制器 -->
<context:component-scan base-package="com.example.controller"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 静态资源处理 -->
<mvc:default-servlet-handler/>
</beans>package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/hello")
public class HelloController {
@GetMapping
public String hello(Model model) {
model.addAttribute("message", "Hello, SpringMVC!");
return "hello"; // 返回视图名称
}
}<!-- /WEB-INF/views/hello.jsp -->
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>Hello SpringMVC</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>除了 XML 配置,SpringMVC 也支持纯 Java 配置。
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
// 创建 Spring 容器
AnnotationConfigWebApplicationContext context =
new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
// 创建 DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(context);
// 注册 Servlet
ServletRegistration.Dynamic registration =
servletContext.addServlet("dispatcher", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}@Configuration
@EnableWebMvc
@ComponentScan("com.example")
public class WebConfig implements WebMvcConfigurer {
// 配置视图解析器
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver =
new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
// 静态资源处理
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}@Controller
@RequestMapping("/user")
public class UserController {
// GET 请求:/user/list
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String list() {
return "user/list";
}
// 简化写法
@GetMapping("/list")
public String list() {
return "user/list";
}
// POST 请求
@PostMapping("/save")
public String save() {
return "redirect:/user/list";
}
}// 单个路径变量:/user/123
@GetMapping("/{id}")
public String getUser(@PathVariable Long id, Model model) {
User user = userService.findById(id);
model.addAttribute("user", user);
return "user/detail";
}
// 多个路径变量:/user/123/orders/456
@GetMapping("/{userId}/orders/{orderId}")
public String getOrder(@PathVariable Long userId,
@PathVariable Long orderId) {
return "order/detail";
}// 查询参数:/user/search?name=张三&age=20
@GetMapping("/search")
public String search(@RequestParam String name,
@RequestParam(required = false) Integer age,
Model model) {
List<User> users = userService.search(name, age);
model.addAttribute("users", users);
return "user/list";
}
// 默认值
@GetMapping("/list")
public String list(@RequestParam(defaultValue = "1") int page) {
return "user/list";
}