SpringMVC
2023/1/1大约 7 分钟
Spring MVC基本概念和功能
Spring MVC是Spring框架的一部分,是基于Java实现MVC设计模式的请求驱动类型的轻量级Web框架。它提供了模型-视图-控制器的架构,可以帮助开发者构建灵活、松耦合的Web应用。下面是Spring MVC的基本概念和功能:
- MVC架构:Spring MVC提供了MVC架构,将应用分为模型(Model)、视图(View)和控制器(Controller)三层,实现关注点分离。
- 前端控制器:Spring MVC提供了DispatcherServlet作为前端控制器,统一处理所有请求,将请求分发给相应的处理器。
- 处理器映射:Spring MVC提供了处理器映射器,可以根据请求URL找到对应的处理器。
- 处理器适配器:Spring MVC提供了处理器适配器,可以执行处理器方法。
- 视图解析器:Spring MVC提供了视图解析器,可以将逻辑视图名解析为物理视图。
为什么要用Spring MVC?
使用Spring MVC有以下几个优点:
- 清晰的角色划分:Spring MVC将应用分为模型、视图和控制器三层,角色划分清晰,职责明确。
- 强大的配置功能:Spring MVC提供了强大的配置功能,可以通过XML或注解进行配置,灵活方便。
- 灵活的URL映射:Spring MVC提供了灵活的URL映射功能,可以将请求URL映射到处理器方法。
- 强大的数据绑定:Spring MVC提供了强大的数据绑定功能,可以将请求参数自动绑定到方法参数。
- 多种视图技术:Spring MVC支持多种视图技术,如JSP、Thymeleaf、FreeMarker等。
总之,使用Spring MVC可以帮助开发者构建灵活、松耦合的Web应用,提高开发效率。
Spring MVC应用场景
Spring MVC主要应用于Web应用开发、RESTful API开发、企业级应用开发等场景,适合构建各种规模的Web应用。
Spring MVC核心组件
Spring MVC的核心组件包括:
- DispatcherServlet:前端控制器,统一处理所有请求,将请求分发给相应的处理器。
- HandlerMapping:处理器映射器,根据请求URL找到对应的处理器。
- HandlerAdapter:处理器适配器,执行处理器方法。
- Handler:处理器,处理请求的业务逻辑。
- ViewResolver:视图解析器,将逻辑视图名解析为物理视图。
- View:视图,渲染响应结果。
Spring MVC核心架构图
+------------------+ +------------------+ +------------------+
| Browser | | Browser | | Browser |
| (浏览器) | | (浏览器) | | (浏览器) |
+------------------+ +------------------+ +------------------+
| | |
| Request | Request | Request
| | |
v v v
+------------------+ +------------------+ +------------------+
| DispatcherServlet| | DispatcherServlet| | DispatcherServlet|
| (前端控制器) | | (前端控制器) | | (前端控制器) |
+------------------+ +------------------+ +------------------+
| | |
| | |
| | |
+------------------+ +------------------+ +------------------+
| HandlerMapping | | HandlerMapping | | HandlerMapping |
| (处理器映射器) | | (处理器映射器) | | (处理器映射器) |
+------------------+ +------------------+ +------------------+
| | |
| | |
| | |
+------------------+ +------------------+ +------------------+
| HandlerAdapter | | HandlerAdapter | | HandlerAdapter |
| (处理器适配器) | | (处理器适配器) | | (处理器适配器) |
+------------------+ +------------------+ +------------------+
| | |
| | |
| | |
+------------------+ +------------------+ +------------------+
| Handler | | Handler | | Handler |
| (处理器) | | (处理器) | | (处理器) |
+------------------+ +------------------+ +------------------+
| | |
| | |
| | |
+------------------+ +------------------+ +------------------+
| ViewResolver | | ViewResolver | | ViewResolver |
| (视图解析器) | | (视图解析器) | | (视图解析器) |
+------------------+ +------------------+ +------------------+
| | |
| | |
| | |
+------------------+ +------------------+ +------------------+
| View | | View | | View |
| (视图) | | (视图) | | (视图) |
+------------------+ +------------------+ +------------------+
| | |
| Response | Response | Response
| | |
v v v
+------------------+ +------------------+ +------------------+
| Browser | | Browser | | Browser |
| (浏览器) | | (浏览器) | | (浏览器) |
+------------------+ +------------------+ +------------------+在上面的架构图中,展示了Spring MVC的核心组件之间的关系:浏览器发送请求到DispatcherServlet,DispatcherServlet通过HandlerMapping找到Handler,通过HandlerAdapter执行Handler,Handler返回ModelAndView,DispatcherServlet通过ViewResolver解析视图,View渲染响应结果返回给浏览器。
Spring MVC快速入门
1、添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>2、配置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">
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>3、配置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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.example"/>
<!-- 开启MVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<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>4、创建Controller
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/list")
public String list(Model model) {
List<User> users = userService.findAll();
model.addAttribute("users", users);
return "user/list";
}
@RequestMapping("/detail/{id}")
public String detail(@PathVariable Long id, Model model) {
User user = userService.findById(id);
model.addAttribute("user", user);
return "user/detail";
}
}5、创建视图
在/WEB-INF/views/user/目录下创建list.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>用户列表</title>
</head>
<body>
<h1>用户列表</h1>
<table>
<tr>
<th>ID</th>
<th>用户名</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.email}</td>
<td><a href="/user/detail/${user.id}">详情</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>Spring MVC常用注解
控制器注解
- @Controller:标识控制器类
- @RestController:组合注解,包含@Controller和@ResponseBody
- @RequestMapping:映射HTTP请求,可以用在类和方法上
- @GetMapping:映射GET请求
- @PostMapping:映射POST请求
- @PutMapping:映射PUT请求
- @DeleteMapping:映射DELETE请求
- @PatchMapping:映射PATCH请求
参数注解
- @RequestParam:绑定请求参数
- @PathVariable:绑定路径变量
- @RequestBody:绑定请求体
- @RequestHeader:绑定请求头
- @CookieValue:绑定Cookie值
- @ModelAttribute:绑定模型属性
- @SessionAttribute:绑定会话属性
响应注解
- @ResponseBody:将返回值作为响应体
- @ResponseStatus:设置响应状态码
- @ExceptionHandler:异常处理
- @ControllerAdvice:全局控制器增强
Spring MVC数据绑定
Spring MVC提供了强大的数据绑定功能,可以将请求参数自动绑定到方法参数。
基本类型绑定
@GetMapping("/user")
public String getUser(@RequestParam Long id, @RequestParam String name) {
// ...
}对象绑定
@PostMapping("/user")
public String saveUser(User user) {
// ...
}数组和集合绑定
@PostMapping("/user/ids")
public String getUserByIds(@RequestParam Long[] ids) {
// ...
}
@PostMapping("/user/names")
public String getUserByNames(@RequestParam List<String> names) {
// ...
}日期绑定
@GetMapping("/user/date")
public String getUserByDate(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
// ...
}Spring MVC数据验证
Spring MVC支持JSR-303数据验证。
1、添加依赖
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>2、在实体类上添加验证注解
public class User {
@NotNull
private Long id;
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度必须在3到20之间")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度必须在6到20之间")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
// getter和setter方法
}3、在Controller中验证
@PostMapping("/user")
public String saveUser(@Valid User user, BindingResult result) {
if (result.hasErrors()) {
return "user/form";
}
userService.save(user);
return "redirect:/user/list";
}Spring MVC拦截器
Spring MVC提供了拦截器机制,可以在请求处理前后进行拦截处理。
1、创建拦截器
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 请求处理前
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 请求处理后,视图渲染前
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 视图渲染后
}
}2、注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login", "/register", "/static/**");
}
}Spring MVC异常处理
Spring MVC提供了多种异常处理方式。
1、@ExceptionHandler
@Controller
public class UserController {
@ExceptionHandler(Exception.class)
public String handleException(Exception e, Model model) {
model.addAttribute("error", e.getMessage());
return "error";
}
}2、@ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(Exception e, Model model) {
model.addAttribute("error", e.getMessage());
return "error";
}
@ExceptionHandler(UserNotFoundException.class)
public String handleUserNotFoundException(UserNotFoundException e, Model model) {
model.addAttribute("error", "用户不存在");
return "error";
}
}Spring MVC文件上传
Spring MVC支持文件上传功能。
1、配置文件上传解析器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10485760); // 10MB
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
}2、创建文件上传Controller
@Controller
public class FileController {
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
String fileName = file.getOriginalFilename();
String filePath = "/upload/" + fileName;
File dest = new File(filePath);
file.transferTo(dest);
}
return "success";
}
}参考链接
https://docs.spring.io/spring-framework/reference/web/webmvc.html
贡献者
cmyshare
