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.rhkb.cn/news/98853.html

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

相关文章

救生员可以戴耳机吗,救生员佩戴蓝牙耳机会影响工作吗?

对于救生员这样一种常驻在水边的职位&#xff0c;戴耳机可以说是比较常见的&#xff0c;佩戴的最主要原因就在于方便进行沟通以及接受指令&#xff0c;以此来确保海边以及海滩等场所的安全&#xff0c;而在这种场景下&#xff0c;对于耳机的考验也是蛮大的&#xff0c;毕竟会出…

计算机视觉之三维重建(二)(摄像机标定)

标定示意图 标定目标 P ′ M P w K [ R T ] P w P^{}MP_wK[R \space T]P_w P′MPw​K[R T]Pw​ 其中 K K K为内参数&#xff0c; [ R T ] [R \space T] [R T]为外参数。该式子需要使用至少六对内外点对进行求解内外参数&#xff08;11个未知参数&#xff09;。 其中 R 3 3 …

js 的正则表达式(二)

1.正则表达式分类&#xff1a; 正则表达式分为普通字符和元字符。 普通字符&#xff1a; 仅能够描述它们本身&#xff0c;这些字符称作普通字符&#xff0c;例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。 元字符&#xff1a; 是一些具有特殊含…

NDK 的配置记录~

NDK 的配置 NDK配置 NDK设置在 AS 路径中设置在 local.properties设置在 build.gradle ndk 和 gradle 对应关系gradle的插件和版本对应关系gradle 插件和NDK对应关系 NDK NDK&#xff08;Native Development Kit&#xff09;是一组工具和库&#xff0c;用于在 Android 平台上开…

[国产MCU]-W801开发实例-GPIO输入与中断

GPIO输入与中断 文章目录 GPIO输入与中断1、硬件准备2、软件准备3、驱动实现4、驱动测试W801的GPIO支持软件配置中断,中断触发方式包含:上升沿触发、下降沿触发、高电平触发、低电平触发。本文在前面[ 国产MCU]-W801开发实例-按键与GPIO输入的基础上实现GPIO中断配置。 1、硬…

C++笔记之基类指针动态地指向某一个子类情况列举

C笔记之基类指针动态地指向某一个子类情况列举 code review! 文章目录 C笔记之基类指针动态地指向某一个子类情况列举1.基本的多态示例2.基类中的成员函数可以设置为纯虚函数3.将基本示例修改为使用智能指针并在堆上实例化子类4.父类指针指向基类后&#xff0c;可以去调用只有…

【Android Framework (十二) 】- 智能硬件设备开发

文章目录 前言智能硬件的定义与应用智能硬件产品开发流程智能硬件开发所涉及的技术体系概述关于主板选型主板CPU芯片的选择关于串口通信 总结 前言 针对我过往工作经历&#xff0c;曾在一家智能科技任职Android开发工程师&#xff0c;简单介绍下关于任职期间接触和开发过的一些…

幼儿园托幼机构管理系统 微信小程序

托幼机构管理系统微信小程序从功能、数据流程、可行性、运行环境进行需求分析。对托幼机构管理系统微信小程序的数据库、功能进行了详细设计&#xff0c;分析了主要界面设计和相关组件设计&#xff0c;托幼机构管理系统微信小程序的具体实现进行了介绍。从数据库中获取数据、向…

.netcore windows app启动webserver

创建controller: using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json.Serialization; using System.Threading.Tasks;namespace MyWorker.…

Linux 进程的地址空间

一、进程 进程&#xff1a;是一个正在运行的程序 PCB : 即是进程控制块&#xff0c;是进程存在的唯一标志。用来描述进程的属性信息&#xff0c;如进程的pid。 每一个进程都是通过fork复制而来的。 在执行fork之后&#xff0c;先将PCB复制一份给子进程&#xff0c;复制之前先…

美国大模型风向速报(一)为何重视提示工程?LangChain+向量数据库+开源大模型真香...

多家&#xff0c;且独家来自美国的信源同时向“亲爱的数据”表示&#xff0c; 提示工程&#xff08;Prompt Engineering&#xff09;在美国大模型领域备受重视。 读者都要聊&#xff0c; 那就干活。 &#xff08;一&#xff09;开源真香 现阶段&#xff0c;AI开源极客大展身手&…

CloudQuery实战 | 谁说没有一款一体化数据库操作管控云平台了?

文章目录 CloudQuery询盾的地址CloudQuery主页统一入口数据库归纳SQL编辑器权限管控审计中心数据保护数据变更 CloudQuery文档中心了解CloudQuery快速入门安装步骤社区版v2.1.0操作手册1数据查询更新日志 CloudQuery社区和活动 CloudQuery线上实战线上实战主页面展示及数据操作…

java实现人物关系抽取

java实现人物关系抽取 人物关系抽取是实体关系抽取的一种情况。实际上是两个过程&#xff1a;命名实体识别和关系抽取。 Java人物关系抽取是指从文本中提取出与Java相关的人物之间的关系。这个过程可以通过自然语言处理和文本分析的方法来实现。具体的步骤包括&#xff1a; 文本…

非常详细的 Ceph 介绍、原理、架构

1. Ceph架构简介及使用场景介绍 1.1 Ceph简介 Ceph是一个统一的分布式存储系统&#xff0c;设计初衷是提供较好的性能、可靠性和可扩展性。 Ceph项目最早起源于Sage就读博士期间的工作&#xff08;最早的成果于2004年发表&#xff09;&#xff0c;并随后贡献给开源社区。在经过…

(7)(7.6) 恢复任务回放

文章目录 前言 7.6.1 配置 7.6.2 工作原理 7.6.3 局限性 前言 本页介绍了什么是"任务继续时后退"功能以及如何使用该功能。 &#xff01;Note 从 4.1 版起&#xff0c;Plane、Copter 和 Rover 均可使用此功能。 在某些应用或运行区域&#xff0c;为了消除冲突&…

okhttp源码简单流程分析

拦截器详细解析可以看大佬简书 "https://www.jianshu.com/p/6fac73f7570f"和 “https://www.jianshu.com/p/3c740829475c” okhttp请求流程 1&#xff1a;OkHttpClient okHttpClient new OkHttpClient.Builder() 构建一个okhttpClient对象&#xff0c;传入你想传入的…

2023国赛数学建模D题思路模型代码 高教社杯

本次比赛我们将会全程更新思路模型及代码&#xff0c;大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…

【IEEE会议】第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023)

第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023&#xff09; 随着大数据时代的到来&#xff0c;对数据获取的随时性和对计算的需求也在逐渐增长。为推动大数据时代的云计算与软件工程的发展&#xff0c;促进该领域学术交流&#xff0c;在CBASE 2022成功举办的…

人工智能在网络安全中的应用: 分析人工智能、机器学习和深度学习等技术在预测、检测和应对网络攻击中的作用

第一章&#xff1a;引言 随着信息技术的迅猛发展&#xff0c;网络安全已成为当今社会不容忽视的重要议题。网络攻击手法日益复杂&#xff0c;传统的防御方法已经不再足够。在这一背景下&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐渐崭露头角&#xff0c;为网络安…

循环神经网络RNN完全解析:从基础理论到PyTorch实战

目录 一、循环神经网络全解1.1 什么是循环神经网络网络结构工作原理数学模型RNN的优缺点总结 1.2 循环神经网络的工作原理RNN的时间展开数学表述信息流动实现示例梯度问题&#xff1a;梯度消失和爆炸总结 1.3 循环神经网络的应用场景文本分析与生成1.3.1 自然语言处理1.3.2 机器…