Spring MVC 中的常见注解的用法

目录

  • 认识 Spring MVC
    • 什么是 Spring MVC
      • MVC 的定义
  • Spring MVC 注解的运用
    • 1. Spring MVC 的连接
      • @RequestMapping 注解
    • 2. 获取参数
      • 获取单个参数
      • 获取多个参数
      • 传递对象
      • 表单传参
      • 后端参数重命名
      • @RequestBody 接收 JSON 对象
      • @PathVariable 获取 URL 中的参数
      • 上传文件 @RequestPart
      • 获取 Cookie/Session/Header
    • 3. 返回数据

认识 Spring MVC

什么是 Spring MVC

Spring MVC(正式名称:Spring Web MVC) 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。

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

MVC 的定义

MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。

在这里插入图片描述

MVC 执行流程:

  1. 用户的请求首先到 Controller
  2. Controller 将请求转发给 Model
  3. Model 处理业务并将数据结果返回给 Controller
  4. Controller 将处理的数据发给 View
  5. View 将数据转换成页面发送给用户

MVC 是⼀种思想,⽽ Spring MVC 是对 MVC 思想的具体实现。
总结来说,Spring MVC 是⼀个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web框架,那么当⽤户在浏览器中输⼊了 url 之后,我们的 Spring MVC 项⽬就可以感知到⽤户的请求.

在创建 Spring Boot 项⽬时,我们勾选的 Spring Web 框架其实就是 Spring MVC 框架。

Spring MVC 注解的运用

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

1. Spring MVC 的连接

首先创建一个 TestController 类,来实现用户与 Spring 程序的交互:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller   //让该类随着 Spring 框架启动而加载
@ResponseBody   //返回非页面数据(这个注解在返回数据中讲解)
//@RestController 相当于@Controller + @ResponseBody
@RequestMapping("/test")   //路由器规则注册(一级路由)
public class TestController {@RequestMapping("/hi")    //路由器规则注册(二级路由)public String sayHi() {System.out.println("hi Spring MVC");return "<h1> 你好 Spring MVC <h1>";}
}

通过浏览器地址访问,来与程序交互:
在这里插入图片描述
在这里插入图片描述
可以看到,通过我们访问地址 http://localhost:8080/test/hi 就可以执行sayHi 方法,并返回字符串到页面上了。

这里注意:
spring mvc 项目默认扫描路径是启动类所在的包下所有的子包,也就是说:我们新建的的类要想放入 IoC 中,就得在该包下创建类。(默认启动类是在 demo 包下)
在这里插入图片描述

@RequestMapping 注解

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

路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射。

@RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类 + ⽅法。
@RequestMapping 也可以直接修饰⽅法,代码实现如下:
在这里插入图片描述
在这里插入图片描述
默认情况下,@RequestMapping 是支持 post 和 get 请求的,我们用 Postman 来验证一下:
get 请求:
在这里插入图片描述
post 请求:
在这里插入图片描述
在有些情况下,我们可能要该注解只支持其中一种请求,那要怎么实现呢?

  1. 只支持 get 请求的注解方式
@RestController
@RequestMapping("/test")
public class TestController {//方式一//下面 value 也可以改为 path@RequestMapping(value = "/hi",method = RequestMethod.GET)public String sayHi() {System.out.println("hi Spring MVC");return "<h1> 你好 Spring MVC <h1>";}//方式二@GetMapping("/hhh")public String hhh() {return "hello world";}
}

这里就只演示一下方式一:
在这里插入图片描述

注意,浏览器通过 url 来访问地址, 默认是 get 请求。
再通过 Postman 来构造一下 post 请求:在这里插入图片描述
2. 只支持 post 请求的注解方式

@RestController
@RequestMapping("/test2")
public class Test2Controller {//方式一@RequestMapping(path = "/hi",method = RequestMethod.POST)public String sayHi() {return "你好";}//方式二@PostMapping("/hhh")public String hhh() {return "你好,世界!";}
}

这里通过浏览器直接访问就报错了:
在这里插入图片描述
通过 Postman 构建 post 请求:
在这里插入图片描述

2. 获取参数

获取单个参数

学习 servlet 时获取参数的写法:

@RestController
@RequestMapping("/user")
public class UserController {//传统写法获取请求中的参数@RequestMapping("/getname") //这里不建议使用大小写, 可以用下划线来区分public String getName(HttpServletRequest request) {return "Name : " + request.getParameter("name");}
}

通过 url 传递参数:
在这里插入图片描述

通过注解获取:

@RestController
@RequestMapping("/user")
public class UserController {//直接获取 url 中的参数//当该路由被触发后,执行到方法时//就会对 name 进行匹配,直接对 name 进行赋值@RequestMapping("/getname2")public String getName2(String name) {return "Name : " + name;}
}

在这里插入图片描述

获取多个参数

其实获取多个参数和获取单个参数差不多:

@RestController
@RequestMapping("/user")
public class UserController {//在传参时,注意参数的命名与要获取的参数名一致@RequestMapping("/getname3")public String getName3(String name, Integer age) {return "Name : " + name + "age : " + age;}
}

不传参数就默认为 null
在这里插入图片描述

在这里插入图片描述

传递对象

顾名思义,就是将参数当做一个对象的部分属性来接收,在接收时我们新建一个 model 层,来存放所需要的对象:在这里插入图片描述

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/add")public User add(User user) {return user;  //将得到的对象返回回去}
}

@Data 注解是个组合注解,它等于:@Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor
添加了它就不需要我们自己写 Getter 和 Setter 方法了,减少重复工作。

在这里插入图片描述
当后端进行接收数据时,就会将参数和 user 里的属性进行对比,发现属性名称与参数的 key 相同就会进行赋值。

当对象返回前端时,因为前端是用 json 来表示对象的,所以返回的对象就转化为 json 格式 :在这里插入图片描述

表单传参

其实表单传参和 url 传参区别就是传递参数的位置不一样,对于后端来说都一样,我们可以用 Postman 来构造请求:
在这里插入图片描述

后端参数重命名

有时候前端传递的 key 你觉得不合理,想改个顺眼的名字,就可以对传递过来的参数重命名,当然前端的参数是不变的。(注意: 对象不能重命名)

@RestController
@RequestMapping("/user")
public class UserController {//将前端参数 y 改为 name,并由 name 接收@RequestMapping("/name")public String name(@RequestParam("y") String name) {return name;}
}

在这里插入图片描述
这里就有一个问题,如果我不传这个 y 就会报错:在这里插入图片描述

在 @RequestParam 中,参数默认是必传的:

我们可以对 @RequestParam 进行
如果我们需求是参数非必传则可以进行如下修改:

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/name")public String name(@RequestParam(value = "y",required = false) String name) {return name;}
}

这样就不会报错了:
在这里插入图片描述

@RequestBody 接收 JSON 对象

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/get_json")public User getJson(@RequestBody User user) {return user;}
}

使用 Postman 构造对象并发送 :
在这里插入图片描述

@PathVariable 获取 URL 中的参数

@RestController
@RequestMapping("/user")
public class UserController {//{aid} 中的 aid 是用来接收参数的@RequestMapping("/get_url/{aid}")//下面的 "aid" 是将参数名为 aid 的参数赋值给后面的 aid//这里两个 aid 名字相同,可以省略参数名("aid")不写public Integer getUrl(@PathVariable("aid") Integer aid) {return aid;}
}

在这里插入图片描述

当然了, 还可以传递多个参数 :

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/get_url2/{aid}/{name}")public String getUrl2(@PathVariable() Integer aid, @PathVariable String name) {return "aid: " + aid + " name: " + name;}
}

在这里插入图片描述

上传文件 @RequestPart

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/upload")//myfile 是接收的参数名, 赋值给 filepublic String upload(@RequestPart("myfile") MultipartFile file) throws IOException {String path = "E:\\image\\img.png";//保存文件file.transferTo(new File(path));return path;}
}

在这里插入图片描述
在这里插入图片描述
该路径下确实保存了 img.png 图片
在这里插入图片描述

上面的代码写法是有问题的, 如果有很多用户都要保存文件, 那文件名就不能写死了, 必须保证每次保存的文件名都不一样, 可以使用 UUID :

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/upload")public String upload(@RequestPart("myfile") MultipartFile file) throws IOException {//得到 UUID 并去掉 "-"String name = UUID.randomUUID().toString().replace("-","");//file.getOriginalFilename() 得到文件名//file.getOriginalFilename().lastIndexOf(".") 得到最后一个"."的下标//整个就是 name 拼接上 .后缀名name += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));String path = "E:\\image\\" + name;//保存文件file.transferTo(new File(path));return path;}
}

多次提交得到的文件 :

在这里插入图片描述

获取 Cookie/Session/Header

  1. 获取 Cookie
@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/get_cookie")public String getCookie(@CookieValue(value = "myCookie", required = false) String ck) {return ck;}
}

没有输出 :
在这里插入图片描述
通过前端构建一个 key 为 myCookie 的 cookie :
在这里插入图片描述

  1. 获取 Session

要想获取 Session 首先要有 Session, 我们可以上传一个 Session :

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/set_session")public String setSession(HttpServletRequest request) {HttpSession session = request.getSession();if(session != null) {session.setAttribute("SESSION_KEY","张三");return "session set success";}return "session set fail";}@RequestMapping("/get_session")public String getSession(@SessionAttribute(required = false, value = "SESSION_KEY") String name) {return name;}
}

在这里插入图片描述
在这里插入图片描述
3. 获取 Header

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/get_header")public String getHeader(@RequestHeader("User-Agent") String userAgent) {return "UserAgent : " + userAgent;}
}

在这里插入图片描述
可以通过 fiddler 来抓包验证一下 :
在这里插入图片描述

3. 返回数据

默认请求下⽆论是 Spring MVC 或者是 Spring Boot 返回的都是 html 格式,如果需要返回非 html 格式数据, 就得使用 @ResponseBody 注解了, 我们之前一直使用的 @RestController 便是 @ResponseBody + @Controller 注解.

验证返回数据的默认格式 :

@Controller
public class Test {@RequestMapping("/b")public String t() {return "hello.html";}
}

因为没有这个前端页面, 所以返回出错 :

在这里插入图片描述
抓包(返回的是 html 格式) :
在这里插入图片描述

在静态文件中加入 hello.html 文件 :

在这里插入图片描述
再次访问 :
在这里插入图片描述

使用 @ResponseBody 返回字符串 :

@Controller
public class Test {@ResponseBody@RequestMapping("/a")public String t2() {return "hello.html";}
}

在这里插入图片描述
或者使用 @RestController 也可以.

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++系列-内存模型

内存模型 内存模型四个区代码区全局区栈区堆区内存开辟和释放在堆区开辟数组 内存模型四个区 不同区域存放的数据生命周期是不同的&#xff0c;更为灵活。 代码区&#xff1a;存放函数体的二进制代码&#xff0c;操作系统管理。全局区&#xff1a;存放全局变量&#xff0c;常…

AutoSAR配置与实践(基础篇)2.5 RTE对数据一致性的管理

传送门 点击返回 ->AUTOSAR配置与实践总目录 AutoSAR配置与实践&#xff08;基础篇&#xff09;2.5 RTE对数据一致性的管理 一、 数据一致性问题引入二、 数据一致性的管理2.1 RTE管理 (SWC间)2.2 中断保护 (SWC内)2.3 变量保护IRVS (SWC内)2.4 Task分配2.5 任务抢占控制 一…

44、TCP报文(二)

接上节内容&#xff0c;本节我们继续TCP报文首部字段含义的学习。上节为止我们学习到“数据偏移”和“保留”字段。接下来我们学习后面的一些字段&#xff08;暂不包含“检验和”的计算方法和选项字段&#xff09;。 TCP首部结构&#xff08;续&#xff09; “数据偏移”和“保…

525. 连续数组

525. 连续数组 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 525. 连续数组 https://leetcode.cn/problems/contiguous-array/description/ 完成情况&#xff1a; 解题思路&#xff1a; 参考代码&#xff1a; …

解放数据库,实时数据同步利器:Alibaba Canal

文章首发地址 Canal是一个开源的数据库增量订阅&消费组件&#xff0c;主要用于实时数据同步和数据订阅的场景&#xff0c;特别适用于构建分布式系统、数据仓库、缓存更新等应用。它支持MySQL、阿里云RDS等主流数据库&#xff0c;能够实时捕获数据库的增删改操作&#xff…

JVM——垃圾回收(垃圾回收算法+分代垃圾回收+垃圾回收器)

1.如何判断对象可以回收 1.1引用计数法 只要一个对象被其他对象所引用&#xff0c;就要让该对象的技术加1&#xff0c;某个对象不再引用其&#xff0c;则让它计数减1。当计数变为0时就可以作为垃圾被回收。 有一个弊端叫做循环引用&#xff0c;两个的引用计数都是1&#xff…

如何用树莓派Pico针对IoT编程?

目录 一、Raspberry Pi Pico 系列和功能 二、Raspberry Pi Pico 的替代方案 三、对 Raspberry Pi Pico 进行编程 硬件 软件 第 1 步&#xff1a;连接计算机 第 2 步&#xff1a;在 Pico 上安装 MicroPython 第 3 步&#xff1a;为 Thonny 设置解释器 第 4 步&#xff…

【ARM-Linux】项目,语音刷抖音项目

文章目录 所需器材装备操作SU-03T语音模块配置代码&#xff08;没有用wiring库&#xff0c;自己实现串口通信&#xff09;结束 所需器材 可以百度了解以下器材 orangepi-zero2全志开发板 su-03T语音识别模块 USB-TTL模块 一个安卓手机 一根可以传输的数据线 装备操作 安…

高项4.项目管理核心技术.

第一部分 项目管理概论 价值驱动的项目管理知识体系: 十二项原则;生命周期四个阶段;五个过程组;十大PM知识领域;八大绩效域;外加价值交付系统; 自1987 年以来, PMBOK 一直是基于过程的项目管理标准的重要代表,项目管理从业者一 直坚持基于过程的项目管理方法。随着…

2023-8-20 单链表

题目链接&#xff1a;单链表 #include <iostream>using namespace std;const int N 100010;int head, e[N], ne[N], idx;void init() {head -1;idx 0; }// 将x插入到头结点 void add_to_head(int x) {e[idx] x;ne[idx] head;head idx;idx; }// 将x插入到下标k后面…

VGG分类实战:猫狗分类

关于数据集 数据集选择的是Kaggle上的Cat and Dog&#xff0c;猫狗图片数量上达到了上万张。你可以通过这里进入Kaggle下载数据集Cat and Dog | Kaggle。 在我的Github仓库当中也放了猫狗图片各666张。 VGG网络 VGG的主要特点是使用了一系列具有相同尺寸 3x3 大小的卷积核进…

Android glide框架及框架涉及到的设计模式

目录 原文链接Android glide框架 简单使用介绍Glide 框架整体结构设计Glide 框架的优点基本使用&#xff1a;Glide占位符 Android glide框架涉及到的设计模式 原文链接 Android glide框架 简单使用介绍 Glide&#xff1a;快速高效的Android图片加载库&#xff0c;可以自动加载…

LLM低成本微调方法

LLM日益流行&#xff0c;已经渗透到各个领域&#xff0c;比如生物医学&#xff0c;但是模型的规模导致微调LLM对普通用户不够友好&#xff0c;因此&#xff0c;我们需要借助一些低成本方法&#xff0c;通过更新少量参数也达到与LLM全参数更新一样的效果。这里介绍三种主流方法&…

改善神经网络——优化算法(mini-batch、动量梯度下降法、Adam优化算法)

改善神经网络——优化算法 梯度下降Mini-batch 梯度下降&#xff08;Mini-batch Gradient Descent&#xff09;指数加权平均包含动量的梯度下降RMSprop算法Adam算法 优化算法可以使神经网络运行的更快&#xff0c;机器学习的应用是一个高度依赖经验的过程&#xff0c;伴随着大量…

解锁Spring AOP的神秘面纱

目录 Spring AOP的组成组成部分与常用注解举例理解 Spring AOP的实现添加 Spring AOP 框架⽀持定义切⾯和切点定义通知切点表达式说明 Spring AOP 实现原理JDK动态代理CGLIB动态代理 Spring AOP作为Spring框架的核心模块&#xff0c;为我们提供了一种优雅的方式来处理横切关注点…

版本控制工具Git集成IDEA的学习笔记(第一篇Gitee)

目录 一、Gitee的使用 1、注册网站会员 2、用户中心 3、创建远程仓库 4、配置SSH免密登录 二、集成IDEA&#xff0c;Git项目搭建 1、本地仓库搭建 1&#xff09;创建一个新项目 2&#xff09;打开终端&#xff0c;在当前目录新建一个Git代码库 3&#xff09;忽略文件 …

3. 爬取自己CSDN博客列表(自动方式)(分页查询)(网站反爬虫策略,需要在代码中添加合适的请求头User-Agent,否则response返回空)

文章目录 步骤打开谷歌浏览器输入网址按F12进入调试界面点击网络&#xff0c;清除历史消息按F5刷新页面找到接口&#xff08;community/home-api/v1/get-business-list&#xff09;接口解读 撰写代码获取博客列表先明确返回信息格式json字段解读 Apipost测试接口编写python代码…

03_缓存双写一致性

03——缓存双写一致性 一、缓存双写一致性 如果redis中有数据&#xff0c;需要和数据库中的值相同如果redis中无数据&#xff0c;数据库中的值要是最新值&#xff0c;且准备回写redis 缓存按照操作来分&#xff0c;可以分为两种&#xff1a; 只读缓存 读写缓存 同步直写操作…

【NX】NX二次开发BlockUI集列表的详细使用步骤

最近使用NX二次开发&#xff0c;需要用到集列表&#xff0c;也就是SetList这个控件&#xff0c;然而网上相关的资料和范例实在是太少&#xff0c;有幸找到《NX二次开发-BlockUI集列表的使用技巧》和《UG&#xff08;NX&#xff09;二次开发 BlockUI 集列表使用方法》&#xff0…

K8S deployment挂载

Deployment部署文件 apiVersion: apps/v1 kind: Deployment metadata:annotations:deployment.kubernetes.io/revision: "1"kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"apps/v1","kind":"Deployment&qu…