JavaEE >> Spring MVC(1)

MVC

MVC:Model View Controller 的缩写,是一种软件架构模式,将软件系统分为模型、视图和控制器三个部分。

  • Mode(模型):是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
  • View(视图):是应⽤程序中处理数据显示的部分。通常视图是依据模型数据创建的。
  • Controller(控制器):是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据, 控制⽤户输⼊,并向模型发送数据。
    在这里插入图片描述
    MVC 是一种思想,而接下来的 Spring MVC 是对这种思想的具体实现。

Spring MVC

也叫做 Spring Web MVC,它是基于 Servlet API 构建的原始 Web 框架。

  1. Spring MVC 是一个 Web 框架;
  2. Spring MVC 是基于 Servlet API 构建的;

Spring MVC 项目该如何创建呢? 其实在前面已经介绍了 Spring Boot 项目的创建,而 Spring MVC 其实就包含在里面了,如下:
在这里插入图片描述

也就是说,Spring MVC 是创建 Spring Boot、Spring 项目的基础,换言之 Spring Boot 、Spring 项目是基于 Spring MVC 的。Spring Boot 是创建 Spring MVC 的一种方式。

Spring MVC 既然是 Web 框架 ,那么就可以使用它将 Java程序和浏览器连接起来,通过访问一个地址能够调用我们的项目,让我们可以见到一个可视化的页面。

Spring MVC 项目创建与连接

Spring MVC 项目与前面 Spring Boot 项目创建与连接方式相同,勾选上 Spring Web ,这样就是 Spring MVC 项目了。
鉴于方式相同,详解请转到前面的文章(Spring Boot 项目创建与连接详解),在此就不在赘述。

补充:
@RequestMapping 注解:是 Spring Web 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接口的路由映射的。

路由映射:当访问一个 URL 的时候,将用户的请求对应到程序中某个类或者某个方法的过程。简单来说,当用户通过URL 访问的时候 ,就会执行程序中对应的方法。例如如下程序:

@RestController
@RequestMapping("/test")
public class UserController {
    @RequestMapping("/sayHi")
    public String sayHi(){
        return "[Spring Boot/MVC] 通过 URL 访问,执行对应方法!!!";
    }
}

通过 URL 进行访问时:
在这里插入图片描述
在这里插入图片描述

  • 对于 @RequestMapping 注解,它即可修饰类,也可修饰方法,修饰类和方法时,访问地址就是类+方法(如上述举例),单独修饰方法的话,访问地址就直接跟方法即可(也就是 http://localhost:8099/sayHi)。
  • @RequestMapping 注解默认会接收 GET、POST、PUT、DELETE、HEAD、OPTIONS 等所有 HTTP 请求方法,若想指定 @RequestMapping 注解来接收别的请求可以参照下面这样做:

首先介绍接收 Get 请求的三种写法:

// 第一种
@RequestMapping("/sayHi")  // 在类/方法前面这样写即可
// 第二种
@RequestMapping(value = "/sayHi",method = RequestMethod.GET) // 设置参数
// 第三种
@GetMapping("/sayHi")

接受 Post 请求的三种写法:

// 第一种
@RequestMapping(value = "/sayHi",method = RequestMethod.POST)
// 第二种
@PostMapping("/sayHi")

其余几种接收 HTTP 请求方法是类似的,如下:
在这里插入图片描述

获取参数

传递/获取单个参数

用户也可以通过 URL 来进行传参,从而在程序中执行。例如在 URL 中输入张三,使之在 Spring MVC 项目中显示出来。
创建一个 Service 类,实现需要传参的方法:

@Service
@ResponseBody
@RequestMapping("/getName")
public class GetService {
    @RequestMapping("g")
    public void setName(String name){
        System.out.println("[Spring Boot/MVC] 从 URL 获取到的 name 为 " + name);
    }
}

启动 Spring MVC 项目,使用 URL 进行传参:

在这里插入图片描述

此时,点击 Send,程序就会接收该 Get 请求,执行方法:

在这里插入图片描述
这样一来,就实现了用户传参与Spring MVC 项目获取/接收参数的“联动”。

传递/获取对象

用户也可以在 URL 中对对象进行传参,例如对 student 对象的 name、age等属性进行传参,Spring MVC 项目中可以自动对该对象的属性进行获取赋值。
创建 Student 对象,创建 Service 类,在类中实现获取对象的方法:

public class Student {
    private String name;
    int age;

    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;
    }
}
@Service
@ResponseBody
@RequestMapping("/stu")
public class StuService {
    @RequestMapping("/get")
    public void getNameAge(Student student){
        System.out.println("name = " + student.getName());
        System.out.println("age = " + student.getAge());
    }
}

启动 Spring MVC 项目,在 URL 中传递参数(对象的属性):
在这里插入图片描述
此时程序中就会获取到传递的对象属性:
在这里插入图片描述

传递/获取多个非对象参数

当我们需要从 URL 中获取用户名、密码等多个内容时,就需要进行多个参数传递,方法如下:

@Service
@ResponseBody
@RequestMapping("/more")
public class TestService {
    @RequestMapping("/pass")
    public void getPassword(String userName,int password){ // 获取多个参数,而不是对象
        System.out.println("userName = " + userName);
        System.out.println("password = " + password);

    }
}

在这里插入图片描述
发送后程序就会接收到并执行 getPassword 方法:

在这里插入图片描述

后端参数重命名(@RequestParam)

对于前端 URL 中传参的 key 值与后端的参数名不匹配,例如前端 URL中传递了一个 name = 张三,而后端用于接受参数的名字为 userName,这样以来就可以使用 @RequestParam 注解来重命名后端参数,将 userName 重命名为 name。具体操作如下:
代码实现:

@Service
@ResponseBody
@RequestMapping("/user")
public class UserService {
    @RequestMapping("/reName")
    public void reName(@RequestParam("name") String userName){  // 使用 @RequestParam 重命名后端参数(userName)
        System.out.println("userName = " + userName);
    }
}

若 URL 中用 userName 进行测试,就会出现问题:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
若使用 name 进行测试,就不会出现问题:
在这里插入图片描述
在这里插入图片描述

这就说明了后端使用 @RequestParam 注解就要求前端必须传递一个 name 参数,否则会报错
对于一些业务,要求一些非必要的参数,例如买东西 app 需要上传资料,性别这一栏填不填都无所谓了,那么该怎么实现呢?
观察 @RequestParam 注解的源码其实就可以知道它还可以设置好多个参数,其中就有 required 这个参数:
在这里插入图片描述
更改上述代码,设置 name 为非必要传参:

@Service
@ResponseBody
@RequestMapping("/user")
public class UserService {
    @RequestMapping("/reName")
    public void reName(@RequestParam(value = "name" ,required = false) String userName){  // 使用 @RequestParam 重命名后端参数(userName)
        System.out.println("userName = " + userName);
    }
}

在这里插入图片描述
在这里插入图片描述
这样就不会出错了,使用 @RequestParam 注解设置 required 参数,就可以实现非必要传参。

使用 @RequestParam 注解还可以接收集合类,例如前端 URL 中传递集合 List ,后端使用 @RequestParam 注解接收 List 集合;

代码实现:

@Service
@ResponseBody
@RequestMapping("/user")
public class UserService {

    @RequestMapping("/list")
    public String getList(@RequestParam("list")List<String> list){
        if (list != null){
            System.out.println(list.toString() + ",size:" + list.size());
            return list.toString() + ",size:" + list.size();
        }
        System.out.println("list 为空");
        return "list 为空";
    }
}

使用 URL 传递 List:
在这里插入图片描述
若不使用 @RequestParam 注解重命名 List,那么就会报错:
在这里插入图片描述
所以当前端传递集合类的时候,必须使用 @RequestParam 注解进行重命名,Spring MVC 项目才能接收到,否则会报错
对于非集合类,如数组,就可以不设置 @RequestParam 注解来进行重命名,项目本身是能接收到的。

@RequestParam 注解小结:

  1. 使用 @RequestParam 注解可以重命名后端参数名称;
  2. 使用 @RequestParam 注解进行重命名时,默认必须传递对应参数的值,否则会报错,当设置 required 参数后就可以实现非必要传参;
  3. 当前端传递集合类时,例如 List 等,必须使用 @RequestParam 注解进行参数重命名来进行接收,否则会报错;
  4. 当前端传递非集合类时,例如数组等,可以不设置 @RequestParam 注解进行重命名,Spring MVC 本身就可以处理接收。

获取 JSON 对象(@RequestBody)

有些时候前端是以 JSON 格式进行传参的,Spring MVC 提供了 @RequestBody 注解用来接收获取 JSON 对象
代码实现:

@Service
@ResponseBody
@RequestMapping("/stu")
public class StuService {
    @RequestMapping(value = "/getjson",method = RequestMethod.POST)
    public void  getJson(@RequestBody Student student){
        System.out.println("student: " + student);
    }
}

使用 JSON 类型进行传参:
在这里插入图片描述
结果如下:
在这里插入图片描述

若在代码中删掉 @RequestBody 注解,Spring MVC 项目就无法接收 JSON 等其它格式:

在这里插入图片描述

获取 URL 中参数(@PathVariable)

使用 @PathVariable 注解可以让我们直接从 URL 中输入张三,99,而不用像 name = 张三 & age = 99 这样写。代码实现如下:

@Service
@ResponseBody
@RequestMapping("/stu")
public class StuService {
    @PostMapping("/re/{name}/{age}")
    public void getUrl(@PathVariable String name, @PathVariable int age){
        System.out.println("name = " + name + "; age = " + age);
    }
}

在这里插入图片描述
在这里插入图片描述
使用 @PathVariable 注解可以让 Spring MVC 项目直接从 URL 中获取对应的属性不需要从前端输入 key = value & key = value… 这样的语句,直接输入属性的值即可。
观察 @PathVariable 注解源码还可以发现:
在这里插入图片描述

上传文件(@RequestPart)

当前端上传一个文件时,后端想要获取的时候,可以通过 @RequestPart 来进行获取,例如前端上传一个文件,由 Spring MVC 项目进行获取并将该文件转移到桌面的一个文件夹中;

@Service
@ResponseBody
@RequestMapping("/f")
public class FileService {
    @RequestMapping("send")
    public String sendFile(@RequestPart MultipartFile file) throws IOException {  // 获取文件名字,将文件放到指定目录下(桌面)
        String fileName = file.getOriginalFilename();
        file.transferTo(new File("C:/Users/lenovo/Desktop/test/" + fileName));   // 将文件转移到桌面 test 文件中
        return "获取上传的文件:" + file.getOriginalFilename();  // 获取文件名字
    }
}

在这里插入图片描述
在这里插入图片描述
当点击上传文件时,这时文件就被程序转移了:
在这里插入图片描述

获取 Cookie/Session

获取 Cookie 一般有两种方式,一种是 Servlet 的方式,一种是 Spring MVC 的方式。
若对 Cookie 和 Session 不是很了解的,放一个传送门,可以去了解下。传送门

Servlet 方式
@Configuration
@ResponseBody
@RequestMapping("cookie")
public class CookieConfiguration {
    @RequestMapping("/getCookie")
    public String getCookie1(HttpServletRequest request){   // 传统方式获取 Cookie
        Cookie[] cookies = request.getCookies(); // 获取 Cookie
        if (cookies != null){
            // 若 Cookie 不为空,将 Cookie 打印出来
            for (Cookie cookie : cookies){
                System.out.println(cookie.getName() +  " : " + cookie.getValue());
            }
            return "获取 Cookie 成功!!!";
        }
        return "获取 Cookie 失败!!!";
    }
}

当我们有 Cookie 的时候就可以打印出 Cookie 的值:
在这里插入图片描述

Cookie 也是可以删除和修改的,可以在如上控制里面将 Cookie 删除:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Spring MVC 注解方式(@CookieValue)

在项目中通过 @CookieValue 注解进行获取指定名称的 Cookie 值,且每次只能获取一个 Cookie 的值

@Configuration
@ResponseBody
@RequestMapping("cookie")
public class CookieConfiguration {

    @RequestMapping("/getCookie2")
    public String getCookie2(@CookieValue("test") String cookieValue){   // 通过注解方式获取 Cookie 的值一次只能获取一次,其中注解中填写的是本次想要获取 Cookie 的名字
        return "获取到指定名 Cookie 的值:" + cookieValue;
    }
}

上述代码指定本次获取名为 test 的 Cookie 的值,结果如下:
在这里插入图片描述

获取 Session 一般也有两种方式,同获取 Cookie 一样,一种是 Servlet 的方式,一种是 Spring MVC 的方式。

Servlet 方式

先设置一个 Session ,然后再对 Session 进行获取:

@Configuration
@ResponseBody
@RequestMapping("/session")
public class SessionConfiguration {
    /*
    * 先设置一个 Session,然后再获取这个 Session
    * */
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("userName","张三");
        return "设置 Session 成功!!!";
    }
    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        String userName = (String) session.getAttribute("userName");   // 通过 Session 名来获取
        return "获取到的登录用户为: " + userName;
    }
}

在这里插入图片描述

获取 Session:

在这里插入图片描述

注解方式(@SessionAttribute)
@Configuration
@ResponseBody
@RequestMapping("/session")
public class SessionConfiguration {
    /*
    * 先设置一个 Session,然后再获取这个 Session
    * */
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("userName","张三");
        return "设置 Session 成功!!!";
    

    /*
    *  Spring Boot 注解方式
    * */
    @RequestMapping("/getSession2")
    public String getSession2(@SessionAttribute("userName") String name){  // 通过设定 Session 名(注解里面写要获取值的名字)来获取值
        return "获取到的登录用户为: " + name;
    }
}

在这里插入图片描述

获取 Header

同样也是上述两种方式:
第一种:通过 Servlet 进行获取:

@Configuration
@ResponseBody
@RequestMapping("header")
public class HeaderConfiguration {
    @RequestMapping("/getHeader")
    public String getHeader(HttpServletRequest request){
        String accept = request.getHeader("Accept");
        return "Accept: " + accept;
    }
}

这样以来就获取到了 header 中的 Accept :
在这里插入图片描述

在这里插入图片描述

第二种:通过 @RequestHeader 注解进行获取.

@Configuration
@ResponseBody
@RequestMapping("header")
public class HeaderConfiguration {

    @RequestMapping("/getHeader2")
    public String getHeader2(@RequestHeader("Accept") String accept){ //获取指定 Header 的值(注解括号里面为想要获取的对象)
        return "Accept:" + accept;
    }
}

在这里插入图片描述

对于 Spring MVC 的相关内容,本文介绍了如何创建,以及一些获取参数相关注解的基本用法,下文将继续介绍 Spring MVC 返回参数的一些用法,即如何使用 Spring Boot/MVC 项目将程序执行业务逻辑之后的结果返回给用户。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/589343.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【通信中间件】Fdbus HelloWorld实例

Fdbus实例教程 Fdbus简介 Fdbus 全称 Fast Distributed Bus&#xff08;高速分布式总线&#xff09;&#xff0c;提供IPCRPC功能。适用于多种OS&#xff1a; LinuxQNXAnroidOSWindow Fdbus本质是Socket&#xff0c;IPC基于Unix domain socket&#xff0c;RPC基于TCP。使用G…

CAMEL:大型语言模型社会的“心智”探索沟通代理

英文名称: CAMEL: Communicative Agents for “Mind” Exploration of Large Language Model Society 中文名称: CAMEL&#xff1a;大型语言模型社会的“心智”探索沟通代理 链接: https://arxiv.org/pdf/2303.17760.pdf 代码: https://github.com/camel-ai/camel 4.4K Star 作…

Scala应用 —— JDBC的创建

文章目录 Scala应用 —— JDBC的创建前言一、JDBC的创建过程1.初始化连接1.1 配置驱动1.2 创建连接对象 2. 初始化执行器2.1 创建执行器对象2.2 初始化执行器参数 3. 执行操作并返回结果 二、Scala JDBC的基本设计思路1. 操作步骤设计2. 解决结果差异化3.实现jdbc方法并输出结果…

53.HarmonyOS鸿蒙系统 App(ArkTS) socket套接字连接失败无效参数--invalid argument

ark ts socket套接字连接失败无效参数--invalid argument 绑定本机真实连接的WIFI的IP&#xff0c;不要绑定127.0.0.1

云原生Kubernetes: K8S 1.29版本 部署Harbor

目录 一、实验 1.环境 2.Linux 部署docker compose 3.证书秘钥配置 4.K8S 1.29版本 部署Harbor 5.K8S 1.29版本 使用Harbor 二、问题 1.docker 登录harbor失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构版本IP备注masterK8S master节点1.2…

Debian操作系统的常用指令介绍

Debian是一个流行的Linux操作系统&#xff0c;以其稳定性和安全性而闻名。对于Debian用户来说&#xff0c;掌握一些基本的命令行指令是非常重要的&#xff0c;因为它们可以帮助你更高效地管理系统。在这篇博客中&#xff0c;我们将介绍一些在Debian系统中常用的指令及其功能。 …

79、贪心-跳跃游戏II

思路&#xff1a; 首先理解题意&#xff1a;从首位置跳最少多少次到达末尾。 第一种&#xff1a;使用递归&#xff0c;将所有跳转路径都获取到进行求出最小值。 第二种&#xff1a;使用动态规划&#xff0c;下一次最优取决上一次的最优解 第三针&#xff1a;贪心&#xff…

区块链 | IPFS 工作原理入门

&#x1f98a;原文&#xff1a;What is the InterPlanetary File System (IPFS), and how does it work? &#x1f98a;写在前面&#xff1a;本文属于搬运博客&#xff0c;自己留存学习。 1 去中心化互联网 尽管万维网是一个全球性的网络&#xff0c;但在数据存储方面&#…

智能消费记账|基于SSM+vue的大学生智能消费记账系统(源码+数据库+文档)

智能消费记账目录 基于SSMvue的大学生智能消费记账系统 一、前言 二、系统设计 三、系统功能设计 1 用户列表 2 预算信息管理 3 预算类型管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1…

R语言的学习—5—多元数据直观表示

1、数据读取 ## 数据整理 d3.1read.xlsx(adstats.xlsx,d3.1,rowNamesT);d3.1 #读取adstats.xlsx表格d3.1数据 barplot(apply(d3.1,1,mean)) #按行做均值条形图 barplot(apply(d3.1,1,mean),las3) barplot(apply(d3.1,2,mean)) #按列做均值图条形图 barplot(a…

Web,Sip,Rtsp,Rtmp,WebRtc,专业MCU融屏视频混流会议直播方案分析

随着万物互联&#xff0c;视频会议直播互动深入业务各方面&#xff0c;主流SFU并不适合管理&#xff0c;很多业务需要各种监控终端&#xff0c;互动SIP硬件设备&#xff0c;Web在线业务平台能相互融合&#xff0c;互联互通&#xff0c; 视频混流直播&#xff0c;录存直播推广&a…

手撕C语言题典——合并两个有序数组(顺序表)

搭配食用更佳哦~~ 数据结构之顺顺顺——顺序表-CSDN博客 数据结构之顺序表的基本操作-CSDN博客 继续来做一下关于顺序表的经典算法题叭~ 前言 88. 合并两个有序数组 - 力扣&#xff08;LeetCode&#xff09; 合并数组也是力扣上关于顺序表的一道简单题&#xff0c;继续来加深…

字节缓冲流

BufferedInputStream() 该类实现缓冲流输出对象&#xff08;可以向底层输出流写入字节而不必为写入的每一个字节导致底层系统的调用&#xff09; BufferedOutputStream() 创建BufferedOutputStream()将创建一个内部缓冲数组 当从流中读取或跳过字节时&#xff0c;内部缓冲区根…

Kubernetes学习笔记06

第十六章、Kubernetes容器交付介绍 如何在k8s集群中部署Java项目 容器交付流程 开发代码阶段 编写代码编写Dockerfile【打镜像做准备】持续交付/集成 代码编译打包制作镜像上传镜像仓库应用部署 环境准备PodServiceIngress运维 监控故障排查应用升级 k8s部署Java项目流程 …

云服务器+ASF实现全天挂卡挂时长

目录 前言正文1.安装下载2.编辑配置文件3.设置Steam社区证书4.启动ASF5.给游戏挂时长6.进阶-ASF自动启动且后台保活 前言 我遇到的最大的问题是&#xff0c;网络问题 其实不然&#xff0c;各大厂商的云服务器后台都有流量监控&#xff0c;意味着依靠一般方法是不能正常访问St…

高手的黑箱:AI时代学习、思考与创作

课程目录 01 不要错过这个时代的巨大红利&#xff0c;AI时代竞争力养成指南.mp4 02 解密高手的黑箱——那些创作高手不告诉你的事.mp4 03 创作&#xff1a;人生发展中最重要的事.mp4 04 创作中最重要的事&#xff08;1&#xff09;&#xff1a;对过程的掌控力.mp4 05 创作…

更深层次理解传输层两协议【UDP | TCP】【UDP 缓冲区 | TCP 8种策略 | 三次握手四次挥手】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 再谈端口号 端口号的返回…

springBootAdmin监控

简介 用于对 Spring Boot 应用的管理和监控。可以用来监控服务是否健康、是否在线、以及一些jvm数据等等 Spring Boot Admin 分为服务端(spring-boot-admin-server)和客户端(spring-boot-admin-client)&#xff0c;服务端和客户端之间采用 http 通讯方式实现数据交互&#xf…

【设计模式】创建者模式之 工厂方法 抽象工厂

工厂方法模式(Factory Method) 一个特定功能&#xff0c;往往有多种实现方式&#xff0c;但是很难有某一个实现可以适用于所有情况&#xff0c;因此往往需要根据特定的场景选择不同的实现。试想&#xff1a;把选择具体实现的代码放在业务中会发生什么&#xff1f;每当我们需要…

【C++】vector类的增删改查模拟实现(图例超详细解析!!!)

目录 一、前言 二、源码引入 三、vector的模拟实现 ✨实现框架 ✨前情提要 ✨Member functions —— 成员函数 ⚡构造函数 ⭐无参构造 ⭐迭代器区间构造 ⭐n个值构造 ⚡拷贝构造 ⚡运算符赋值重载 ⚡析构函数 ✨Element access —— 元素访问 ⚡operator[ ] …