Java Spring MVC -01
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);
}
}