Java Spring MVC 超详解介绍

Spring MVC 是 Spring 框架中用于构建 Web 应用程序的模块,它采用了 MVC 模式(Model-View-Controller)。Spring MVC 的核心目标是将业务逻辑、数据层、以及展示层分离,使得代码清晰易维护。

Spring MVC 的架构

1. 核心组件

  • DispatcherServlet(分发器)
    • Spring MVC 的核心组件,是前端控制器 (Front Controller)。
    • 接收所有的 HTTP 请求,协调其他组件完成请求处理,并最终返回响应。
  • HandlerMapping(处理器映射器)
    • 根据请求 URL 找到对应的处理器(Controller)。
  • Controller(控制器)
    • 处理具体的请求逻辑,接收请求参数,调用服务层或数据层,返回模型数据或视图名。
  • ViewResolver(视图解析器)
    • 将逻辑视图名解析为具体的视图(例如 JSP 文件、Thymeleaf 页面等)。
  • ModelAndView(模型和视图对象)
    • 用于存储返回给视图的数据和视图名称。

Spring MVC 工作流程

  1. 用户发送请求:请求被 DispatcherServlet 捕获。
  2. 处理器映射:DispatcherServlet 使用 HandlerMapping 找到对应的处理器(Controller)。
  3. 调用处理器:将请求传递给具体的 Controller 方法处理。
  4. 返回数据:Controller 返回一个 ModelAndView 对象,包含模型数据和视图名称。
  5. 视图解析器处理:ViewResolver 将逻辑视图名解析为具体视图文件。
  6. 渲染视图:视图层(如 JSP 或 Thymeleaf)结合模型数据生成响应。
  7. 返回响应:响应通过 DispatcherServlet 返回给用户。

Spring MVC 核心注解

1. @Controller

标记一个类为控制器,处理 HTTP 请求。

@Controller
public class MyController {
    @RequestMapping("/hello")
    public String sayHello() {
        return "hello"; // 返回视图名
    }
}

2. @RequestMapping

用于映射请求 URL 到处理方法,可以用于类或方法上。

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/profile")
    public String getUserProfile() {
        return "userProfile"; // 显示用户资料页面
    }
}

3. @RestController

@Controller@ResponseBody 的结合,用于构建 RESTful APIs。

@RestController
@RequestMapping("/api")
public class ApiController {
    @GetMapping("/greeting")
    public String greeting() {
        return "Hello, World!"; // 直接返回字符串
    }
}

4. @GetMapping / @PostMapping / @PutMapping / @DeleteMapping

简化了 @RequestMapping,用于特定的 HTTP 方法。

@RestController
public class MyController {
    @GetMapping("/users")
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }
}

5. @RequestParam

绑定请求参数到方法参数。

@RequestMapping("/welcome")
public String welcome(@RequestParam("name") String name, Model model) {
    model.addAttribute("name", name);
    return "welcome";
}

6. @PathVariable

绑定 URL 中的变量到方法参数。

@RequestMapping("/user/{id}")
public String getUserById(@PathVariable("id") Long id, Model model) {
    model.addAttribute("user", userService.findUserById(id));
    return "userDetails";
}

7. @ModelAttribute

将请求参数绑定到 Java 对象,并将对象添加到模型。

@PostMapping("/register")
public String register(@ModelAttribute User user) {
    userService.saveUser(user);
    return "registrationSuccess";
}

8. @ResponseBody

用于直接将数据写入 HTTP 响应体,常用于 RESTful API。

@RequestMapping("/json")
@ResponseBody
public User getUser() {
    return new User("John", "Doe");
}

Spring MVC 配置

1. 配置 DispatcherServlet

通常通过 web.xml 或 Java 配置来注册。

web.xml 配置:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Java 配置:

@Configuration
@EnableWebMvc
@ComponentScan("com.example")
public class WebConfig implements WebMvcConfigurer {
    // 配置 ViewResolver 等其他组件
}

2. 配置视图解析器

指定如何解析逻辑视图名。

@Bean
public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    return resolver;
}

常见示例

1. 简单页面跳转

Controller:

@Controller
public class PageController {
    @RequestMapping("/home")
    public String home() {
        return "home"; // 视图名对应 /WEB-INF/views/home.jsp
    }
}

2. 返回 JSON 数据

Controller:

@RestController
@RequestMapping("/api")
public class ApiController {
    @GetMapping("/users")
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
}

RESTful API 和 MVC 的结合

通过 @RestController 和 Jackson,Spring MVC 非常适合构建 RESTful API。

  • @RestController 自动将返回对象序列化为 JSON。
  • 使用 @RequestBody 反序列化 JSON 请求体为 Java 对象。
  • 使用 ResponseEntity 处理复杂响应。
@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findUserById(id);
        if (user == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(user);
    }

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = userService.saveUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
}

总结

Spring MVC 提供了一个强大的、模块化的框架,能轻松构建传统 Web 应用和 RESTful API。它的核心在于分离关注点,通过一系列注解和灵活的配置,使开发者专注于业务逻辑的实现。

发布者:myrgd,转载请注明出处:https://www.object-c.cn/4348

Like (0)
Previous 2024年11月21日 下午8:48
Next 2024年11月21日 下午9:01

相关推荐

  • 在 Spring Boot 中实现定时任务,可以使用以下三种方式

    1. 使用 @Scheduled 注解 这是 Spring 提供的简单方式,基于注解实现定时任务。 步骤: 3. 创建任务类使用 @Scheduled 注解定义定时任务: 4. @Scheduled 参数详解 2. 使用 ScheduledExecutorService 如果任务管理需要更灵活,可以使用 Java 自带的线程池。 示例: 3. 使用 Quar…

    2024年11月26日
    3600
  • Java 8 到 Java 17 的升级涉及一些关键变化

    JDK 8 升级到 JDK 17 指南Java 8 到 Java 17 的升级涉及一些关键变化,包括语言特性、API 更新和性能改进。以下是一些升级要点:语法和语言特性:记录类(Record Class):Java 14 引入了记录类,提供了一种简化创建不可变数据对象的方式。密封类(Sealed Classes):Java 15 引入了密封类,允许开发者限制…

    2024年11月27日
    5900
  • 在 Spring Boot 中实现定时任务,通过 Spring Task Scheduling 来完成

    在 Spring Boot 中实现定时任务,可以通过 Spring Task Scheduling 来轻松完成。Spring 提供了多种方法来调度任务,其中使用 @Scheduled 注解是最常见且简单的方式。 步骤:在 Spring Boot 中实现定时任务 1. 启用定时任务 首先,确保在 Spring Boot 应用的主类或配置类中启用定时任务功能: …

    2024年11月26日
    5100
  • 微信小程序设计和实现一个校园音乐应用的方法

    基于微信小程序设计和实现一个校园音乐平台,主要包括以下几个方面的设计与功能实现: 1. 需求分析 1.1 功能需求 1.2 非功能需求 2. 技术架构设计 2.1 前端:微信小程序 2.2 后端 2.3 技术栈 3. 数据库设计 表结构示例: 4. 功能实现 4.1 用户登录与注册 4.2 音乐播放 4.3 歌单与榜单 4.4 评论功能 5. 部署与优化 5…

    2024年11月26日
    6200
  • Android Studio 国内镜像,加速下载和构建过程

    在国内使用 Android Studio 时,由于访问 Google 的官方资源(如 Gradle 和 SDK)速度较慢甚至无法访问,可以通过配置国内镜像源来加速下载和构建过程。以下是详细配置步骤: 1. 配置 Gradle 国内镜像 Gradle 是 Android Studio 构建项目的重要工具,其依赖库通常托管在 Google Maven 和 JCe…

    2024年11月25日
    42100
  • 在使用 Kettle 9.1 连接 MySQL 时,遇到错误提示 Connection failed. Verify all connection parameters and confirm that the appropriate driver is installed.

    在使用 Kettle 9.1 连接 MySQL 时,遇到错误提示 Connection failed. Verify all connection parameters and confirm that the appropriate driver is installed. 通常是由于以下几个原因导致的: 1. MySQL 驱动未正确配置Kettle 需要…

    2024年11月27日
    5600
  • 在进行 Java 单元测试时,遇到找不到类名的错误

    在进行 Java 单元测试时,遇到找不到类名的错误,通常是由于以下几个原因引起的。下面是一些常见问题及其解决方法:1. 类路径(Classpath)问题最常见的原因是编译后的类文件没有正确地包含在类路径中,或者类文件没有被正确加载到测试框架中。要解决这个问题,确保以下几点:解决方法:确认类是否存在:首先确保测试类和目标类都已经编译,并且在正确的目录中。检查 …

    2024年11月28日
    3700
  • 在Java中 ArrayList 和 LinkedList 实现 List 接口类

    在Java中,ArrayList 和 LinkedList 都是实现了 List 接口的类,但它们在底层实现和使用场景上有显著的区别。以下是它们的主要区别: 1. 底层实现ArrayList基于动态数组实现。元素是连续存储的,每个元素都可以通过索引直接访问。LinkedList基于双向链表实现。每个元素由节点(Node)存储,节点包含数据和前后节点的引用。 …

    2024年12月2日
    4900
  • synchronized 和自适应锁

    Java 中的 synchronized 是一种常用的线程同步机制,它通过内置的锁(监视器锁,Monitor Lock)来保护代码块或方法的并发安全。从 JDK 1.6 开始,synchronized 进行了许多优化,其中一个重要的机制是自适应锁(Adaptive Spinning)。 1. 什么是自适应锁? 自适应锁是一种优化锁竞争和线程上下文切换性能的技…

    2024年11月21日
    6300
  • 在使用 VS Code 和 Keil 协同开发 STM32 程序

    在使用 VS Code 和 Keil 协同开发 STM32 程序时,可以利用 Keil 强大的编译器 和 VS Code 的高效代码编辑功能,结合起来提高开发效率。以下是实现协同开发的详细步骤: 前置准备安装 Keil确保已安装 Keil MDK-ARM,并配置好开发环境。Keil 下载地址:Keil 官方网站安装 VS Code下载并安装最新版本的 VS …

    2024年12月1日
    10300
  • 在 Spring Boot 中实现 Callback 回调的常用方法

    在 Spring Boot 中实现 Callback(回调) 通常用于处理外部系统调用你的服务接口。例如,当一个第三方服务完成某项操作后通知你的应用完成结果。以下是实现回调的完整流程: 1. 回调的基本流程 2. 示例代码 2.1 创建回调接口 假设第三方服务会通过 POST 请求回调数据到 /callback,并发送如下 JSON 数据: 实现代码如下: …

    2024年11月24日
    5200
  • java中使用 Arrays.asList()新增报错问题解决方法

    Arrays.asList() 返回的是一个固定大小的列表。如果你尝试使用该列表进行添加、删除等修改操作,会抛出 UnsupportedOperationException 异常。这是因为 Arrays.asList() 返回的列表背后是一个数组,它的大小是固定的,不能进行动态修改。解决方法使用 ArrayList 包装 Arrays.asList() 的结…

    2024年12月2日
    3300
  • 在使用 HBase 时,遇到 Unable to find region for 错误问题

    在使用 HBase 时,遇到 Unable to find region for 错误通常是由于以下几个原因引起的:HBase RegionServer 未启动或无法连接表的 Region 分布信息不一致Zookeeper 配置问题客户端连接配置问题HBase 版本不兼容下面是一些常见的原因和解决办法:1. 确保 HBase 服务正常运行首先检查你的 HBa…

    2024年11月29日
    7800
  • 使用 Redis 和 Spring Cache 实现基于注解的缓存功能

    Spring Cache 提供了一种简单的方法来通过注解对方法的返回结果进行缓存。结合 Redis,可以构建一个高效的分布式缓存解决方案。以下是详细实现步骤: 1. 引入必要的依赖在 pom.xml 文件中添加以下依赖(适用于 Spring Boot 项目): 2. 配置 Redis在 application.yml 或 application.proper…

    2024年12月1日
    4600
  • java算法— 动态规划之斐波那契数列模型

    斐波那契数列是动态规划中一个经典的模型,其递推关系简单易懂,非常适合作为入门练习。斐波那契数列的定义如下: 在 Java 中,可以通过递归、带记忆化的递归、迭代和优化空间复杂度的方式实现斐波那契数列。 1. 递归实现 最直观的实现,但存在大量重复计算,时间复杂度为 O(2n)。 2. 带记忆化的递归 通过一个数组存储已计算的值,避免重复计算,时间复杂度降为 …

    2024年11月21日
    4500

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信