1. SpringMVC 核心概念
- 作用:简化 Web 开发,实现 MVC 模式,专注于请求处理、数据绑定和响应生成。
- 核心组件:
- DispatcherServlet:中央控制器,接收所有请求。
- HandlerMapping:映射请求到具体控制器方法。
- HandlerAdapter:调用控制器方法并处理返回结果。
- ViewResolver:解析视图名称,生成最终响应。
2. 入门案例关键点
- 项目结构:
src/main/java ├── com.itheima.controller │ └── UserController.java ├── com.itheima.config │ ├── SpringMvcConfig.java │ └── ServletContainersInitConfig.java └── pom.xml
- 配置流程:
- 导入依赖:Spring-webmvc、Servlet API。
- 配置类:
@Configuration @ComponentScan("com.itheima.controller") @EnableWebMvc // 开启 JSON 转换等功能 public class SpringMvcConfig {}
- Servlet 初始化类:
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
- 控制器示例:
@RestController // @Controller + @ResponseBody @RequestMapping("/users") public class UserController { @GetMapping("/{id}") public User getUser(@PathVariable Integer id) { return new User(id, "张三", 20); } }
下面为你提供一个简单的 SpringMVC 入门案例,这个案例主要实现接收客户端请求并返回响应结果。这里使用 Maven 来管理项目依赖。
步骤 1:创建 Maven 项目
首先,创建一个 Maven Web 项目,在pom.xml
文件中添加必要的依赖:
<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.example</groupId>
<artifactId>springmvc-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.28</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>
步骤 2:配置 web.xml
在src/main/webapp/WEB-INF
目录下创建web.xml
文件,配置DispatcherServlet
:
<?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>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
步骤 3:配置 Spring MVC
在src/main/webapp/WEB-INF
目录下创建spring-mvc-config.xml
文件,配置 Spring MVC:
步骤 4:创建控制器
在src/main/java/com/example/controller
目录下创建HelloController.jav
步骤 5:部署和运行
将项目打包成 WAR 文件并部署到 Servlet 容器(如 Tomcat)中,启动容器。
步骤 6:测试
在浏览器中访问http://localhost:8080/springmvc-demo/hello
,你应该能看到Hello, Spring MVC!
的响应信息。
3. 请求与响应处理
参数接收:
类型 示例代码 说明 普通参数 public String save(String name, Integer age)
自动绑定 URL 或表单参数。 POJO public String save(@RequestBody User user)
接收 JSON 数据,需 @RequestBody
。路径参数 public String delete(@PathVariable Integer id)
匹配 URL 中的 {id}
。日期参数 public String date(@DateTimeFormat(pattern="yyyy-MM-dd") Date date)
自定义日期格式。 响应处理:
- JSON 响应:直接返回对象,依赖
@RestController
或@ResponseBody
。 - 页面跳转:返回视图名(需配置视图解析器)。
- JSON 响应:直接返回对象,依赖
4. RESTful 风格开发
- 核心注解:
@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
。@PathVariable
绑定路径参数。
- 示例:
@PostMapping public String addBook(@RequestBody Book book) { /* ... */ } @DeleteMapping("/{id}") public String deleteBook(@PathVariable Integer id) { /* ... */ }
5. 查缺补漏
静态资源处理:
- 需配置
WebMvcConfigurer
放行静态资源:@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/static/"); } }
- 需配置
异常处理:
- 使用
@ControllerAdvice
和@ExceptionHandler
全局处理异常:@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) @ResponseBody public Map<String, Object> handleException(Exception ex) { return Map.of("code", 500, "msg", "服务器内部错误"); } }
- 使用
拦截器:
- 实现
HandlerInterceptor
接口,配置拦截路径:public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 登录验证逻辑 return true; // 放行 } }
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/admin/**"); // 拦截路径 } }
- 实现
数据验证:
- 使用
@Valid
和BindingResult
校验请求参数:public String save(@Valid @RequestBody User user, BindingResult result) { if (result.hasErrors()) { return result.getFieldError().getDefaultMessage(); } // 业务逻辑 }
- 使用
文件上传:
- 配置
MultipartResolver
,使用@RequestParam("file") MultipartFile file
接收文件。
- 配置
6. 常见问题与解决方案
- 404 错误:
- 检查
@RequestMapping
路径是否正确。 - 确保静态资源路径在
WebMvcConfigurer
中放行。
- 检查
- JSON 转换失败:
- 确认
jackson-databind
依赖已添加。 - 检查
@EnableWebMvc
是否配置。
- 确认
- 中文乱码:
- 配置
CharacterEncodingFilter
:@Override protected Filter[] getServletFilters() { CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding("UTF-8"); filter.setForceRequestEncoding(true); return new Filter[]{filter}; }
- 配置
7. 总结
- 核心流程:请求 → DispatcherServlet → HandlerMapping → 控制器方法 → 响应。
- 关键注解:
@RestController
、@RequestMapping
、@RequestBody
、@PathVariable
。 - 最佳实践:
- 使用
@RestController
简化 JSON 响应。 - 分离配置类(SpringMVC 与 Spring 基础配置)。
- 全局处理异常和拦截器提升代码健壮性。
- 使用
常见的注解
在 Spring MVC 里,注解的使用能简化开发流程,增强代码的可读性与可维护性。下面为你详细介绍 Spring MVC 中常见的注解。
控制器相关注解
@Controller
:用来把一个类标记成 Spring MVC 的控制器。此注解会让 Spring 框架识别该类,进而处理客户端的请求。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@RequestMapping("/test")
@ResponseBody
public String test() {
return "Test response";
}
}
@RestController
:这是@Controller
与@ResponseBody
的组合注解。当一个类使用@RestController
注解时,其所有方法的返回值都会被当作响应体直接返回,常用于构建 RESTful 风格的服务。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@RequestMapping("/restTest")
public String restTest() {
return "REST test response";
}
}
请求映射注解
@RequestMapping
:能够把 HTTP 请求映射到控制器的方法上。它可对请求的 URL、请求方法(GET、POST 等)、请求参数等进行配置。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class RequestMappingController {
@RequestMapping(value = "/getData", method = RequestMethod.GET)
@ResponseBody
public String getData() {
return "Data from GET request";
}
@RequestMapping(value = "/postData", method = RequestMethod.POST)
@ResponseBody
public String postData() {
return "Data from POST request";
}
}
@GetMapping
:@RequestMapping(method = RequestMethod.GET)
的快捷方式,专门用于处理 HTTP GET 请求。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GetMappingController {
@GetMapping("/getInfo")
public String getInfo() {
return "Info from GET request";
}
}
@PostMapping
:@RequestMapping(method = RequestMethod.POST)
的快捷方式,专门用于处理 HTTP POST 请求。
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PostMappingController {
@PostMapping("/submitData")
public String submitData() {
return "Data submitted successfully";
}
}
@PutMapping
:@RequestMapping(method = RequestMethod.PUT)
的快捷方式,用于处理 HTTP PUT 请求,一般用于更新资源。
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PutMappingController {
@PutMapping("/updateData")
public String updateData() {
return "Data updated successfully";
}
}
@DeleteMapping
:@RequestMapping(method = RequestMethod.DELETE)
的快捷方式,用于处理 HTTP DELETE 请求,通常用于删除资源。
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DeleteMappingController {
@DeleteMapping("/deleteData")
public String deleteData() {
return "Data deleted successfully";
}
}
请求参数注解
@RequestParam
:用于从请求的 URL 参数中获取值,并将其绑定到控制器方法的参数上。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RequestParamController {
@RequestMapping("/getParam")
public String getParam(@RequestParam("name") String name) {
return "Name: " + name;
}
}
@PathVariable
:用于从请求的 URL 路径中获取参数值。
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PathVariableController {
@RequestMapping("/user/{id}")
public String getUser(@PathVariable("id") int id) {
return "User ID: " + id;
}
}
@RequestBody
:用于将请求体中的数据绑定到控制器方法的参数上,通常用于处理 JSON 或 XML 格式的数据。
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
class User {
private String name;
private int age;
// Getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@RestController
public class RequestBodyController {
@PostMapping("/addUser")
public String addUser(@RequestBody User user) {
return "User added: " + user.getName() + ", Age: " + user.getAge();
}
}
其他注解
@ModelAttribute
:有两种用途,一是在方法参数上使用时,可将请求参数绑定到模型对象;二是在方法上使用时,可将该方法的返回值添加到模型中。@SessionAttributes
:用于将模型中的属性存储到 HTTP 会话中。
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
@Controller
@SessionAttributes("userName")
public class SessionAttributesController {
@RequestMapping("/addSessionAttribute")
public String addSessionAttribute(Model model) {
model.addAttribute("userName", "John");
return "success";
}
@RequestMapping("/getSessionAttribute")
public String getSessionAttribute(@ModelAttribute("userName") String userName) {
return "User name from session: " + userName;
}
}
@ExceptionHandler
:用于处理控制器中抛出的异常。
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExceptionHandlerController {
@RequestMapping("/throwException")
public String throwException() {
throw new RuntimeException("An error occurred");
}
@ExceptionHandler(RuntimeException.class)
public String handleException(RuntimeException e) {
return "Error: " + e.getMessage();