Spring MVC

2023-12-16

Spring MVC 是什么

Spring MVC 全称 Spring Web MVC,又称为 Spring Web

  • Spring MVC 是一个 Web 框架
  • Spring MVC 是基于 Servlet API 构建的

什么是 MVC

“MVC” 代表模型-视图-控制器(Model-View-Controller)。这是一种设计模式,用于构建具有良好组织结构的应用程序,以便更好地管理代码和提高可维护性。

img

  • Model 代表应用程序中处理数据和业务逻辑的部分。在Spring MVC中,模型通常由Java对象组成,这些对象负责封装和处理数据,以及执行与应用程序相关的业务逻辑。
  • View 负责渲染和显示模型的数据。在Web应用中,视图通常是用户界面的一部分,负责将模型的数据以用户友好的方式呈现出来。视图不处理业务逻辑,它只关注如何正确地显示数据。
  • Controller 是模型和视图之间的中介,负责接收用户的输入,处理用户请求,并更新模型和视图。它将用户的请求路由到适当的模型处理程序,然后将模型的数据传递给适当的视图进行显示。控制器的目标是保持模型和视图之间的解耦,使应用程序更加灵活和易于扩展。

如何学习 Spring MVC

学习 Spring MVC 最关注以下 3 个功能:

  1. 连接 :将用户(浏览器)和 Java 程序连接起来,也就是访问一个地址能够调用到我们的 Spring 程序。
  2. 获取参数 :用户访问的时候会带一些参数,在程序中要想办法获取到参数
  3. 输出数据 :执行业务逻辑之后,把程序执行的结果返回给用户

Spring MVC 创建和连接

在创建 Spring Boot 项目的时候,我们已经引入了 Spring Web 依赖,引入这个依赖,我们的项目就是一个 Spring MVC 项目。

例:通过访问 http://127.0.0.1:8080/web/hi 来返回 Hello

package com.example.spring_mvc_demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller // 类注解,在 Spring 启动的时候加载并注册
@ResponseBody // 当前类返回的非静态页面
@RequestMapping("/web") // 当使用 /web 可以访问到当前类
public class WebController {
    @RequestMapping("/hi") // 当使用 /web/hi 可以访问到当前方法
    public Object hi() {
        return "Hello";
    }
}
  • @ResponseBody 用于标识控制器方法的返回值应该直接作为 HTTP 响应的主体部分,而不是视图解析器渲染成视图。
  • @RequestMapping 可以应用在类级别和方法级别,用于定义 URL 映射规则,将 HTTP 请求映射到相应的控制器方法上。

结果:

img

注意:

  • 如果不加 @ResponseBody ,那么返回的就是一个视图,也就是 html 文件的路径
  • @Controller 不可替换为其他类注解(如 @Service @Component

@RestController ,相当于 @Controller + @ResponseBody

更简单的写法:

package com.example.spring_mvc_demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebController {
    @RequestMapping("/hi") // 当使用 /hi 可以访问到当前方法
    public Object hi() {
        return "Hello";
    }
}

访问 http://127.0.0.1:8080/hi 就可以看到 Hello 了。

@RequestMapping 默认支持所有请求方法,可以通过指定 method 属性使其只匹配某一种请求方法:

@RequestMapping(value = "/greet", method = RequestMethod.GET)
public String greet() {
    return "greet";
}

在较新的 Spring 版本中, @RequestMapping 已经被更具体的注解取代,例如 @GetMapping @PostMapping @PutMapping @DeleteMapping ,它们分别用于处理 GET POST PUT DELETE 请求。这些注解提供了更清晰和简洁的方式来定义映射规则

如:

@RequestMapping(value = "/greet", method = RequestMethod.GET)
// 等效于
@GetMapping("/greet")

获取参数

传统方式

Spring MVC 兼容 Servlet 的用法

@RestController
public class WebController {
    @GetMapping("/hi") // 当使用 /hi 可以访问到当前方法
    public Object hi(HttpServletRequest request, HttpServletResponse response) {
        return "Hello" + request.getParameter("name");
    }
}

在 Spring MVC 中默认内置隐藏了两个参数,HttpServletRequest 和 HttpServletResponse,想要用只要声明这两个参数即可

简便的方式

直接声明要获取的参数,参数名和查询字符串的参数名一致

@GetMapping("/get1")
public String getParam1(String name) {
    return "value: " + name;
}

结果:

img

参数的类型也可以写成其他的,比如 int 或 Integer,类型会自动转换

@GetMapping("/get1")
public String getParam1(Integer age) {
    return "value: " + age;
}

如果查询字符串中没有指定 age 参数,那么这里会显示 null,如果 int 类型,则会报错,因为 int 无法接收 null

获取一个自定义类的对象

先定义一个类:

package com.example.spring_mvc_demo.model;

import lombok.Data;

@Data
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
}

然后就可以获取这个类的对象,对象的属性会自动从查询字符串中获取

@GetMapping("/get2")
public String getParam2(Student student) {
    return student.toString();
}

img

从 json 字符串获取对象

上面的方式,传输的数据都是 application/x-www-form-urlencoded 格式,也就是查询字符串的格式。

Json 字符串是另外一种格式,要获取其解析后的对象,只要在参数的声明前加 @RequestBody 注解

@PostMapping("/login3")
public HashMap<String, Object> login3(@RequestBody Student student) {
   HashMap<String, Object> result = new HashMap<>();
   result.put("id", student.getId());
   result.put("name", student.getName());
   result.put("age", student.getAge());
   return result;
}

我们使用 HashMap 作为返回类型,Spring 会自动将其转换为 JSON 格式作为 HTTP 响应返回给客户端

使用 Postman 构造请求并验证:

img

获取文件

使用 MultipartFile 类来描述一个文件,前面加上 @RequestPart 注解

@RequestPart 注解,用于处理HTTP请求中的"multipart/form-data"类型的数据来支持文件上传

该注解可以传入参数,比如, @RequestPart("myfile") 注解表示将请求中名为"file"的部分映射到 MultipartFile file 参数上

@PostMapping("/reg")
public String reg(@RequestPart("myfile") MultipartFile file) throws IOException {
    file.transferTo(new File("d:/img.png"));
    return "success";
}

使用 MultipartFile 中的方法 transferTo ,将文件保存到硬盘。

获取 Cookie/Session/Header

获取 Cookie

@CookieValue 注解,用于从 HTTP 请求中提取特定 Cookie 的值,并将其映射到控制器方法的参数上。

注解中传入参数,比如 @CookieValue("cookie") 表示提取名为"cookie"的 Cookie 的值

@GetMapping("/getck")
public String getCookie(@CookieValue("cookie") String cookie) {
    return "cookie: " + cookie;
}

在浏览器中手动添加 cookie,可以看到服务端成功获取并返回了:

img


获取 Header

@RequestHeader 注解 用于从 HTTP 请求头中提取特定的信息,并将其映射到控制器方法的参数上。

传入参数指定要提取的请求头的名称。

@GetMapping("/gethead")
public String getHead(@RequestHeader("User-Agent") String userAgent) {
    return "User-Agent: " + userAgent;
}

session 存储和获取

@GetMapping("/setSession")
public String setSession(HttpServletRequest request) {
    // 获取 HttpSession 对象
    HttpSession session = request.getSession();

    // 存储数据到会话中
    session.setAttribute("username", "john_doe");

    return "redirect:/getSession";
}

@GetMapping("/getSession")
public String getSession(HttpSession session, Model model) {
    // 从会话中获取数据
    String username = (String) session.getAttribute("username");

    return "sessionResult: " + username;
}

和原始的 Servlet 没有区别,这里不做赘述。

参数重命名

@RequestParam 用于指定要提取的参数名称,这样,参数名和前端的查询字符串的名称就可以不一样了。

@GetMapping("/gettime")
public String getTime(@RequestParam("t") String time) {
    return "time: " + time;
}

img

非必传参数

在Spring MVC中,你可以通过在方法参数上使用 @RequestParam 注解,并设置 required 属性为 false 来表示一个参数是非必传的。默认情况下, @RequestParam required 属性是 true ,即参数是必传的。

@Controller
public class MyController {

    @GetMapping("/example")
    public String exampleMethod(
            @RequestParam(name = "optionalParam", required = false) String optionalParam) {
        // 处理参数
        if (optionalParam != null) {
            // 参数存在时的处理逻辑
            System.out.println("Optional Parameter: " + optionalParam);
        } else {
            // 参数不存在时的处理逻辑
            System.out.println("Optional Parameter is not provided");
        }

        // 其他业务逻辑

        return "exampleView";
    }
}

如果请求中包含了该参数,则参数值会被传递到方法中;如果请求中没有包含该参数,方法中的 optionalParam 将为 null

获取url路径中的参数

如下代码 其中 {name} {password} 是占位符,表示路径中的变量

@PathVariable 注解:用于将 URI 模板变量映射到方法的参数上。

@RequestMapping("/login4/{name}/{password}")
public String login4(@PathVariable String name, @PathVariable String password) {
    return "name: " + name + ", password: " + password;
}

img

请求转发和请求重定向

区别

  1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务端转发
  2. 请求重定向地址发生变化;请求转发地址不发生变化
  3. 请求重定向与直接访问新地址效果一样,不存在原来的外部资源不能访问;请求转发服务端转发有可能造成原外部资源不能访问

在Spring MVC中,“forward:” 和 “redirect:” 是用于控制器方法返回视图的两个关键字。

例:

@Controller
public class TestController {
    // 请求转发
    @RequestMapping("/hello1")
    public Object hello1() {
        return "forward:/login.html";
    }
    // 请求重定向
    @RequestMapping("/hello2")
    public Object hello2() {
        return "redirect:https://www.baidu.com";
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring MVC 的相关文章

  • JAVA GENERICS错误:具有相同的擦除,但两者都没有覆盖另一个[重复]

    这个问题在这里已经有答案了 为了好玩 我正在创建一个排序框架 以更好地理解各种排序算法 而且 我试图使其足够通用 以便它可以对实现扩展可比较接口的接口的任何内容进行排序 然而 java 编译器对我不满意 这是我的界面 public inte
  • Spring MVC 415 不支持的媒体类型

    我正在使用 Spring 3 2 并尝试使用 ajax post 请求来提交 json 对象数组 如果这是相关的 我转义了所有特殊字符 我收到的 HTTP 状态为 415 我的控制器是 RequestMapping value save p
  • C++ 中的模块路径到 Java JNI 调用

    当我用 C 创建 Java 8 JVM 时 我通常使用类似以下代码的内容来告诉 JVM 类路径 JavaVMOption options new JavaVMOption 1 JVM invocation options options 0
  • 编译错误:computeFrames 选项不支持 JSR/RET

    当我编译 java 文件时 在 IntelliJ 项目上出现此错误 没有列出特定的源文件 但它失败并出现此错误 删除以下编译器标志可修复该错误 source 1 5 target 1 5 然而 这些需要在那里 因为我们的目标是 Java 5
  • Hibernate vs JPA vs JDO - 各自的优缺点? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我熟悉 ORM 这个概念 几年前我什至在 NET 项目中使用过 nHibernate 然而 我还没有跟上 Java 中 ORM 的主题
  • 相机 java.lang.RuntimeException:setParameters 失败

    我使用创建了一个自定义相机应用程序this https github com davidgatti dgCam源代码 但在少数设备上 例如高分辨率设备 我得到 RuntimeException setParameters failed 我面
  • 如何告诉 RestTemplate 使用 UTF-8 编码进行 POST?

    我在使用 RestTemplate 发布采用 UTF 8 编码的 JSON 时遇到问题 JSON 的默认编码是 UTF 8 因此媒体类型甚至不应该包含字符集 我尝试将字符集放入 MediaType 但它似乎无论如何都不起作用 My code
  • HK2 MethodInterceptor 与 Jersey 资源

    如何设置aopMethodInterceptor使用泽西岛资源 这是我尝试过的 如下this https hk2 java net 2 2 0 aop example html文档 第 1 步 拦截服务 public class MyInt
  • 原生状态栏

    有没有办法创建nativeSWT 中的状态栏与 Windows 应用程序中的状态栏类似 我见过使用标签模拟的状态栏 但我对真正的解决方案更感兴趣 org eclipse jface action StatusLineManager crea
  • 从 Android Intent 打开图库应用

    我正在寻找一种打开方式Android来自意图的画廊应用程序 我不想返回图片 而是只是打开图库以允许用户使用它 就像他们从启动器中选择它一样 View pictures folders 我尝试执行以下操作 Intent intent new
  • 来自公共字符串的 Android RSA 加密

    我正在开发一个 Android 应用程序 我希望用户能够使用其他人的公钥加密消息 系统将生成公钥 私钥对 然后可以将消息秘密发送给其他用户 我正在创建一个加密类 它将处理消息的加密 解密 不幸的是我遇到了一些问题 在这种方法中 我想传递用户
  • 如何一次又一次地使用同一个迭代器?

    给出下一个代码 这是某个大型方法的一部分 ArrayList
  • 用于将类文件转换为 Java 源代码的 Eclipse 插件 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 当源不可用时 是否有可用的 Eclipse 插件来反编译类文件 从 class 文件生成 java 源代码 类似于 Resharper 在
  • 从内存中获取Java类字节码(经过多次转换)

    我正在为 Minecraft 开发一个 coremod 并在加载许多类时对其进行转换 然而问题是 有多个 coremod 也转换了与我相同的类 并且我遇到了一些我想研究的奇怪行为 那么问题来了 经过多次转换后的字节码如何检查呢 当我转换它时
  • 如何使用 Solr 索引 pdf 内容?

    我正在尝试使用 SolrJ 索引一些 pdf 文档 如下所述http wiki apache org solr ContentStreamUpdateRequestExample http wiki apache org solr Cont
  • 如何正确使用 FirefoxOptions() 及其参数将其传递给 FirefoxDriver() 构造函数

    我在实例化 FirefoxDriver 时尝试使用 FirefoxOptions 如下所示 FirefoxOptions options new FirefoxOptions WebDriver localWebDriver new Fir
  • 构造函数中的同步块

    我有一个带有静态变量的类 如下所示 private static Object sMyStaticVar 如果我想在构造函数中为这个 var 赋值 我有这样的代码 if sMyStaticVar null sMyStaticVar new
  • 从 Java 读取 /dev/input/js0

    我正在尝试阅读 dev input js0来自Java 但我不断得到 java io IOException Invalid argument at java io FileInputStream read0 Native Method a
  • Android 回调监听器 - 将 SDK 中的 pojo 的值发送到应用程序的 Activity

    我有一个深埋在 SDK 中的 java 类 它执行一个操作并返回一个布尔值 它不知道应用程序的主要活动 但我需要主要活动来接收该布尔值 我见过很多关于回调 广播和监听器的问题 但他们似乎都了解该活动 我的 pojo 确实有一个 Activi
  • Java 中的 ConcurrentHashMap 和 Hashtable [重复]

    这个问题在这里已经有答案了 Java 中的 ConcurrentHashMap 和 Hashtable 有什么区别 哪个对于线程应用程序更有效 ConcurrentHashMap 和 Hashtable 锁定机制 Hashtable属于Co

随机推荐

  • UART设备

    UART简介 UART Universal Asynchronous Receiver Transmitter 通用异步收发传输器 UART作为异步串口通信协议的一种 工作原理是将传输数据的每个字符一位接一位地传输 是在应用程序开发过程中使
  • 欧盟eDelivery的AS4解决方案

    为实现绿色和数字欧洲的愿景 欧盟启动了 数字欧洲计划 DEP 总预算为75 9亿欧元 重点是将数字技术带给企业 公民和公共行政部门 它将建立数字能力和基础设施 并以创建数字市场为目标 主要通过与成员国在先进计算和数据 人工智能和网络安全 私
  • HAL库学习

    CMSIS简介 CMSIS Cortex Microcontroller Software Interface Standard 微控制器软件接口标准 由ARM和其合作的芯片厂商 ST NXP 软件工具厂商 KEIL IAR 共同制定的标准
  • I/O设备模型

    I O设备模型 绝大部分的嵌入式系统都包括一些I O Input Outut 输入 输出 设备 例如仪器上的数据显示屏 工业设备上的串口通信 数据采集设备上用于保存数据的Flash或SD卡 以及网络设备的以太网接口等 I O设备模型框架 R
  • PIN设备

    引脚简介 芯片上的引脚一般分为4类 电源 时钟 控制与I O I O在使用模式上又分为General Purpose Input Output 通用输入 输出 简称GPIO 与功能复用I O 如SPI I2C UART 大多数MCU的引脚都
  • CleanMyMac X2024免费许可证(激活教程)

    CleanMyMac X是一款流行的系统优化工具 专为Mac用户设计 它可以帮助用户清理Mac系统中的垃圾文件 卸载不需要的程序 加速Mac性能以及保护Mac系统的安全 一 简介 CleanMyMac X是一款功能强大的系统优化工具 它可以
  • 中断管理学习

    中断管理 什么是中断 简单的解释就是系统正在处理某一个正常事件 忽然被另一个需要马上处理的紧急事件打断 系统转而处理这个紧急事件 待处理完毕 再恢复运行刚才被打断的事件 生活中 我们经常会遇到这样的场景 当你正在专心看书的时候 忽然来了一个
  • MacBook电脑内存容量小根本不够用?如何一键解决?

    得益于M1系列芯片的强势表现 很多朋友都换用了MacBook 首次接触到了macOS系统 但出乎意料的是 很多人就开始受罪了 明明这么出色的硬件 为何到处都不顺手呢 尤其是容量 MacBook相比同价位的Windows笔记本 硬盘本来就偏小
  • FL Studio21最新FL水果编曲软件中文版在哪下载?

    FL Studio21水果编曲软件是一款专业的音乐制作软件 被广泛地应用于电子音乐 hip hop 流行乐等多种音乐类型的制作 该软件提供了丰富的音频编曲工具和音乐效果器 让用户可以轻松地创作出高品质的音乐作品 同时 这也是一款非常易于上手
  • CleanMyMac X2024(Mac优化清理工具)v4.14.5中文版

    CleanMyMac X是一款颇受欢迎的专业清理软件 拥有十多项强大的功能 可以进行系统清理 清空废纸篓 清除大旧型文件 程序卸载 除恶意软件 系统维护等等 并且这款清理软件操作简易 非常好上手 特别适用于那些刚入手苹果系统的宝宝们 只需两
  • flstudio21.3.2304高级版水果编曲音乐软件

    flstudio高级版是一款适用于广泛领域的音频编辑软件 它支持多通道混音器和VST插件 包括数百种乐器和效果插件 它还为您提供了一个乐谱编辑器 需要对不同乐器的节奏进行必要的编辑 Flstudio具有许多内置电子合成声音 可提供更广泛的电
  • fl studio2024水果21.3免费汉化版

    fl studio2024全称Fruity Loops Studio2024 这款软件也被人们亲切的称之为水果 它是一款功能强大的音乐创作编辑软件 拥有全功能的录音室 大混音盘以及先进的音乐制作工具 用户通过使用该软件 就可以轻松制作出自己
  • 【408】计算机学科专业基础 - 计算机组成原理

    一 计算机系统概述 复习提示 本章是组成原理的概述 考查时易针对有关概念或性能指标出选择题 也可能综合后续章节的内容出有关性能分析的综合题 掌握本章的基本概念 是学好后续章节的基础 部分知识点在初学时理解不深刻也无须担忧 相信随着后续章节的
  • 汽车EDI:Chrysler EDI项目案例

    菲亚特克莱斯勒汽车Fiat Chrysler Automobiles FCA 是一家全球性汽车制造商 主营产品包括轿车 SUV 皮卡车 商用车和豪华车等多种车型 其旗下品牌包括菲亚特 克莱斯勒 道奇 Jeep Ram 阿尔法 罗密欧和玛莎拉
  • 物流EDI:COSCO的EDI对接

    当产品的原产地和最终目的地之间以及生产商和分销商之间实现了即时 安全和高效通信 意味着业务已经取得成功 无论是在物理层面的货物运输 还是在数据层面的信息交互 物流在供应链中都是至关重要的一环 物流发展进程的加快能够促进供应链各个环节实现完美
  • 解决 vue3 使用mitt(发布订阅库)时,多次触发事件订阅问题

    问题起源 在日常vue项目开发中 有时会用到mitt 前身事件总线mittBus 进行事件传递 然而使用经常就是mitt emit mitt on 就结束了 未考虑到取消订阅事件 订阅事件会创建回调函数 并将其添加到事件总线中 如果在实例卸
  • MyBatis——Java 持久层框架

    文章目录 MyBatis 是什么 准备工作 创建一个数据库和表 引入依赖 配置连接字符串和 MyBatis MyBatis 组成 MyBatis 使用步骤 定义一个类
  • VSCode中如何查看EDI报文?

    VSCode是开发人员常用的一款软件 为了降低EDI报文的阅读门槛 知行的开发人员设计了EDI插件 可以在VSCode中下载使用 如何打开一个EDI报文 VSCode EDI插件介绍 EDI插件下载流程 进入VSCode 打开Extensi
  • 【腾讯云AI绘画】与AI绘画和解,和AI绘画共成长

    前言 六月份的时候 买了腾讯AI绘画的资源包 可当通过API去使用AI绘画后 我顿时就被整破防了 于是写了一篇文章 算是无声控诉 被腾讯云AI绘画整破防了 再回首 腾讯绘画不仅提供了API调用 还构建了 智能图像创作平台 用于提供AI绘画在
  • Spring MVC

    文章目录 Spring MVC 是什么 什么是 MVC 如何学习 Spring MVC Spring MVC 创建和连接 获取参数 传统方式 简便的方式 获取一个自定义类的对象 从 json 字符