Spring Web MVC(常用的注解@RequestMapping,@RequestParam,@RequestBody等)

news2024/11/14 2:07:43

一、Spring MVC

spring的启动类

启动类是看这个 @SpringBootApplication 注解,而不是 类的名字

这个注解在哪,哪个类就是启动类

1.MVC思想

举例

二、Spring MVC

mvc 是一种思想,而spring mvc是对mvc思想的一种实现。全称是 spring web mvc,基于servlet API 构建的web的框架。 

spring mvc看一看作称一个模块,被包含在 spring框架中。

1、建立连接

1)@RequestMapping(“/路径名”):使用这个注解,建立连接

1.1作用域
1.1.1 作用在 方法 上(访问 直接使用 方法路径 即可)

在 demo 包里,创建一个UserController 类,写一个return hello 的方法,在方法前给上 注解 @RequestMapping(‘/hello’)

启动服务器后,发现并没有访问到

原因是,在项目中会有很多个方法,spring不会一个一个检查每一个方法前面是否有 @RequestMapping注解,所以在这里报错了。

在类的前面加上 @RestController

然后就能正常显示了

1.1.2 作用在 类 上(访问路径就成了 类路径+方法路径)

在 user controller类前,加上@RequestMapping 注解

(多个注解之间无优先顺序之分,同时生效)

再用之前的hello路径访问,就没有效果了

 此时需要加上 类 的路径,就能成功访问了

访问的路径,可以是多层的

同时在以往servlet 里,路径里的里的第一个 / ,是要加上的。

但是在 spring 里,这第一个 / ,可加可不加,一样是能正常访问的。

建议还是加上

1.2 请求方式 get 和 post 都支持

使用postman 发送get 和post请求,再用fiddler 抓包

发现 @RequestMapping  这两种方法(get 和post) 都可以

postman的简单介绍

2)指定请求方式

        既然 get 和 post 两种方式都支持,那如果有些方法只能通过某种特定的方式访问,不希望通过其他方式访问的时候,就可以指定HTTP请求方式。 

指定请求方式:

@RequestMapping(value = “/路径名”,method = RequestMethod.方法名)

在括号里,=左边 为属性名,=右边为属性值,多个属性之间使用逗号隔开

@RequestMapping 里的属性

给注解里,指定HTTP请求方法为 get


 

重新启动之后

        get请求能正常拿到返回值 hello

        此时post请求,无法访问了,提示 method not allowed(方法不被允许),就是说请求方式错了。

        这也说明了,指定方法get之后,只能通过get访问了

2、发送请求 @RestController

2.1请求

2.1.1 请求单个参数

例子1:

例子2:

假设没有传参进去,会有怎样的效果

  服务器错误

5开头错误一般是服务器问题,查看后端日志,找问题

(一段一段看,从后往前看,看每段的第一行)

因为定义方法中参数类型是基本类型 int,所以访问的url不写参数是,默认被当作null空值,发送请求了。

        而 null,无法传入到 int 类型中,所以报错了

修改代码,将参数类型改为包装类型 Integer

再次试验

这次就正常响应了

2.1.2 传递多个参数

在接收多个参数时,url地址栏传参的顺序可以变化

 只需要保证这里的属性名相同就行

2.1.3 当参数比较多的时候,可以创建一个对象,作为传入参数 

例如现在要传递的参数有 Integer id,String name,Integer age

此时创建一个对象 UserInfo 

在直接传参时,使用基本数据类型,如果 url里没有写参数,会报错。只能写包装类型。

(2.1.1 请求单个参数 例子2)

        而传递的参数是 对象 时,可以使用基本数据类型

当 传递对象的 id 数据类型是 Integer 时,不传id,返回的是null

当把 Integer 修改为 int 基本类型时,不会报错,返回的是 0 (默认值)

2.2 对参数重命名@RequestParam("新名字")

2.2.1 重命名后,用新名字访问,否则报错 400

原本传递的参数名应该是 usernmae,但是修改为 name后

在url地址栏就应该是 name了

使用重命名后的参数名 name 就可以访问了

当使用原来的参数名username访问时,报错 400

2.2.2 重命名后,默认该参数成为必传项,不传会报错 400;也可修改为非必传项 required = false ;

修改 required = false ,就可以不用传这个参数了

修改为非必传项后,不传递该参数,就不会报错了

 2.3 请求参数为数组 

第一种传递方式:一个参数里有多个值

第二种传递方式:有多个参数名相同的值传递时

2.4 请求参数为 顺序表 List(集合@RequestParam 来绑定参数关系)

发现报错500 ,服务器这边出现问题 

 

查看日志

对于list接口,没有找到构造函数

原因是:spring中规定了,请求中相同参数名的多个值,默认封装到数组。要想封装到集合,需要用 @RequestParam 来绑定参数关系

而这里的请求参数为list,是集合,所以要用 @RequestParam 绑定list

修改代码

发现绑定list之后,能正常访问了

同样的,加上 @RequestParam注解之后,该参数默认就为必传项了,不传会报错

如果想修改为 非必传项,就需要 加上 requeired = false

但是发现 现在又是 500 的错误了,解决完400的错误,现在是服务器端的错误了

查看日志

错误原因,list是null空指针

于是在服务器代码里,添加一个空指针的判断

解决问题了

2.5 传递 JSON 数据

         json是一个字符串,key : value这样的键值对,key 只能是字符串(引号引起来的),而value可以是字符串、数字、布尔、数组、list等;多个键值对之间用 都好分隔

对象用{}表示,数组用[]表示,json就是用{}或者[],将键值对包含起来的

        在工作中广泛使用

JSON对象的创建

请求 Json 数据 @RequestBody

直接在 Params这里是没有用的,报了400的错误,客户端这边的问题,传递数据的方式有问题

查看日志

发现请求正文没有

重新传递正确Json数据

2.6 请求 URL 中的参数 @PathVariable

常见的网站也可能使用这样的方式,例如CSDN、今日头条

{}里面是定义的路径

2.6.1单个路径变量

 2.6.2多个路径变量

要按照这个路径规则访问,才能正常访问 假设不按照规则访问,例如故意将类型为Integer 的 age写成 字符

就会发生错误

2.6.3 同时被 @PathVariable 注解 修饰后,也会变成 必填项

如果不填也会报错

2.6.4 重命名

2.7 上传文件 @RequestPart

2.7.1 获取原始文件名 .getOriginalFilename()

代码中的 MultipartFile 是文件的类型,自定义文件名为 file

在下面这张图测试发送请求的时候, key 也要与这里的 file 对应上

2.7.2 将获取的到的文件,转移到新的目录下 .transferTo

目的路径下找到了该文件

测试了 ,不加注解 @RequestPart 也能正常上传,但是还是建议加上,不然不知道以后会不会有其他的问题。

重命名之后,新的名字newfile 也要与 请求中的 key值 newfile 对应上,否则就会出现以下的错误

正确请求应该是 newfile

2.8 获取 cookie 和 session

2.8.1 cookie和session的概念
cookie和 session

举例:

1.用户提供账号和密码,服务器进行验证

2.服务器验证通过,会把信息存储在session中,并且把 sessionId 返回给客户端(通过set - Cookie 的方式)

3.客户端收到响应,吧sessionID 存储在Cookie中

4.后续的请求中,客户端带着SessionId 去请求(带着 Cookie 信息去请求)

共同点:

都是会话机制

区别:

1.虽然都是保存用户信息的一种机制,但是

        cookie是客户端机制

        session是服务器机制

2.cookie 和 session 主要是通过 session ID 关联起来的,session ID 是cookie 和 session 之间的桥梁。

3.cookie 和 session 通常是一起出现配合使用的,但不是必须配合。

        完全可以用 cookie 来保存一些数据在客户端。这些数据不一定是用户身份信息,也不一定是sessionID。

        session 中的 sessionID 也不需要非得通过 Cookie/set-Cookie 传递,比如通过URL 传递。

2.8.2 获取cookie
2.8.2.1 传统方式 servlet 获取 cookie

启动之后,发现报错了

查看日志,发现是空指针问题

修改代码

可以在浏览器设置cookie

再次刷新,成功获取到 cookie了

在日志中可以看到获取的cookie 值,这个就是刚才在浏览器中设置的cookie值

在postman里也可以设置cookie

2.8.2.2 Springboot 获取 cookie (使用注解@CookieValue)

传统的方式 :使用 servlet 获取 cookie 是获取到的所有的 cookie

而 spring boot 只能获取一个 特定的 cookie,使用注解 @CookieValue("对应的cookie名")

现在有两个Cookie

先使用 传统方式 获取所有cookie

在日志里看到了所有的 cookie

再使用 spring boot 的方式 获取 指定的 ameris 这个cookie

获取成功

 2.8.3 获取session
2.8.3.1 传统方式获取 session

 

一开始获取 session 为空

设置 session 的 参数之后

就能成功获取到 session了

 2.8.3.2 Spring boot方式获取 session (使用注解 @SessionAttribute)

发现报错了

原因是 加上注解之后,session里面这个 userName属性 变成必传项了,如果不传就会报错

修改代码

2.9 获取 header

 2.9.1 传统方式获取 header(HttpServletRequest )

当使用postman发送请求时,获取的User-Agent(用户代理:显示请求时所用的浏览器相关信息)就是 postman

使用谷歌浏览器,响应的就是谷歌浏览器的相关信息

  2.9.2 Spring boot方式获取 header(使用注解 @RequestHeader("要获取的字段名"))

总结 请求的几个注解

@RestController 在代码最前面写上,将方法返回的结果直接作为响应内容发送到客户端。(只返回数据,不返回页面)

@RequestMapping("/路径名") 通过URL进行路由映射 。既是类注解,又是方法注解。

访问的URL路径 = 类路径+方法路径

指定请求方式:@RequestMapping(value = “/路径名”,method = RequestMethod.方法名)

@RequestParam(“重命名参数”)和绑定(“绑定集合类型对象比如List”)

@RequestBody 请求Json格式数据

@PathVariable 请求URL 中的变量

@RequestPart 上传文件

获取cookie

传统使用servlet获取所有的cookie,spring使用的是@CookieValue(“cookie”) 获取指定的cookie

获取session

传统使用servlet,spring使用的是@SessionAttribute(“session的字段名”)获取session会话中指定的字段

获取header

传统使用servlet,spring使用的是@RequestHeader(“header的字段名”)获取header会话中指定的字段

3.响应 @Controller

3.1 返回静态页面

先在static包下写一个index页面

在浏览器直接访问这个页面的方法

static目录下的页面,直接写在  “127.0.0.1:端口号/"  后面

如果 static目录下还有文件夹,则需要写上 文件夹名/页面名

写了响应代码,最开始使用@RestController

期望的结果是,响应index这个页面内容

这里的 /index.html中 的 / ,指的是127.0.0.1:端口号

 

当访问r1时,响应的不是 index页面 ,而是一个字符串

然后将注解改成 @Controller

发现返回了正确的 index页面

3.1.2 @Controller  与 @RestController 的区别

@RestController源码

@Target 指的是使用范围 。TYPE指的是类,METHOD指的是方法。

@Retention 指的是生命周期。

SOURCE:生命周期为编译期间。 CLASS:类中存活。 RUNTIME:代码运行期间。(最长寿)

@Document 指的是一些文档。

前面三个注解是 元注解,就是能给其他注解前面注解。

@Controller 默认返回的是页面
@RestController = @Controller (管理spring中的代码)+ @ResponseBody(仅返回数据本身)

所以在最开始,使用@RestController,原本期望返回index页面,结果只返回了数据本身,也就是 “/index.html” 这个字符串。

在改成@Controller后,就返回的是对应的index.html这个页面了。

3.2 返回数据 (@ResponseBody)
 那在@Controller 下只想返回数据本身怎么办?
加上 @ResponseBody 这个注解就好了.

@ResponseBody源码

既能修饰类,也能修饰方法。

        修饰类:该类下所有方法,返回的仅仅是数据本身。

        修饰方法:该方法返回的仅仅是数据本身。

3.3 返回HTML片段
返回HTML片段,其实就是 HTML标签语言

由于返回的HTML语句本质上还是数据本身,不是页面,所以要写上注解 @ResponseBody

3.4 返回JSON格式、js格式、css格式等
Spring会根据返回的数据类型,自动转换相应的格式。

当返回类型是 对象 时,自动转换为 JSON格式

当返回的是Map,自动转换为 JSON

 

当返回的是 js 页面,响应时自动转换为 application/javascript

当返回的是css文件时,响应自动转换为 text/css 格式

 

 3.5 设置响应头(状态码,编码,或者其他header)
3.5.1设置响应的状态码

状态码的设置,不影响页面的显示

3.5.2 设置content-type

content-type:默认是 html

指定返回的类型  @RequestMapping(value = "/r9",produces = "application/json")

3.5.3 自定义Header

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

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

相关文章

【线程系列之五】线程池介绍C语言

一、基本概念 1.1 概念 线程池(Thread Pool)是一种基于池化技术管理线程的机制,旨在减少线程创建和销毁的开销,提高系统资源的利用率,以及更好地控制系统中同时运行的线程数量。线程池通过预先创建一定数量的线程&am…

FFMPEG提取音频流数据

FFmpeg是一套开源的计算机程序,主要用于记录、转换数字音频、视频,并能将其转化为流。它提供了录制、转换以及流化音视频的完整解决方案,被誉为多媒体业界的“瑞士军刀”。 1.使用ffmpeg命令实现音频流数据提取 [wbyqwbyq ffmpeg]$ ffmpeg …

全局 loading

好久不见! 做项目中一直想用一个统一的 loading 状态控制全部的接口加载,但是一直不知道怎么处理,最近脑子突然灵光了一下想到了一个办法。 首先设置一个全局的 loading 状态,优先想到的就是 Pinia 然后因为页面会有很多接口会…

减分猫-12123货车驾驶证(学法减分)专用题目及答案 #知识分享#媒体

想要顺利通过驾驶考试,掌握一些常考题目和答案是非常有必要的。今天,我就为大家带来了这样一份资料——20道驾驶考试题目和答案解析,让你考试更有底气!这些题目和答案不仅包括了考试中的重点和难点内容,还有针对每道题…

leetcode力扣_二分查找

69.x的平方根 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。 示例 1&…

神经网络构造

目录 一、神经网络骨架:二、卷积操作:三、卷积层:四、池化层:五、激活函数(以ReLU为例): 一、神经网络骨架: import torch from torch import nn#神经网络 class CLH(nn.Module):de…

微信小程序 vant-weapp的 SwipeCell 滑动单元格 van-swipe-cell 滑动单元格不显示 和 样式问题 滑动后删除样式不显示

在微信小程序开发过程中 遇到个坑 此处引用 swipeCell 组件 刚开始是组件不显示 然后又遇到样式不生效 首先排除问题 是否在.json文件中引入了组件 {"usingComponents": {"van-swipe-cell": "vant/weapp/swipe-cell/index","van-cell-gro…

视频共享融合赋能平台LntonCVS视频监控业务平台技术方案详细介绍

LntonCVS国标视频综合管理平台是一款智慧物联应用平台,核心技术基于视频流媒体,采用分布式和负载均衡技术开发,提供广泛兼容、安全可靠、开放共享的视频综合服务。该平台功能丰富,包括视频直播、录像、回放、检索、云存储、告警上…

【C++开源】GuiLite:超轻量UI框架-入门

开发环境说明 使用visual Studio 2022进行开发 下载源码 从如下的网址进行源码和示例代码的下载: GitHub源码网址为:idea4good/GuiLite示例代码路径为:idea4good/GuiLiteExample使用方法 GuiLite是一个仅有头文件的一个库,使用的时候直接include到自己的UIcode.cpp文件…

Golang面试题整理(持续更新...)

文章目录 Golang面试题总结一、基础知识1、defer相关2、rune 类型3、context包4、Go 竞态、内存逃逸分析5、Goroutine 和线程的区别6、Go 里面并发安全的数据类型7、Go 中常用的并发模型8、Go 中安全读写共享变量方式9、Go 面向对象是如何实现的10、make 和 new 的区别11、Go 关…

Elasticsearch 企业级实战 01:Painless 脚本如何调试?

在企业级应用中,Elasticsearch 常常被用来处理复杂的数据查询和操作。 Painless 是 Elasticsearch 的内置脚本语言,虽然强大,但调试起来并不容易。 本文将详细介绍如何在实战中有效调试 Painless 脚本,以提高开发和运维效率。 本文…

打印室预约小程序的设计

管理员账户功能包括:系统首页,个人中心,用户管理,附近打印店管理,文件打印管理,当前预约管理,预约历史管理,打印记录管理 开发系统:Windows 架构模式:SSM JD…

微分段Microsegmentation简介

目录 微分段Microsegmentation简介什么是微分段?微分段的防范措施微分段的防护层级 基于网络的微分段微分段基本工作机制微分段的角色VxLAN的额外字段 业务链分组与传输策略场景1:三层报文本地转发场景场景2:三层报文跨设备转发场景 微分段的…

微信小程序与本地MySQL数据库通信

微信小程序与本地MySQL数据库通信 因为本地MySQL服务器没有域名,也没有进行相应的请求操作封装,因此微信小程序没办法和数据库通信。 但是对于开发人员来说,没有数据库,那还能干撒?虽然我尝试过用json-server&#x…

Android音视频—OpenGL 与OpenGL ES简述,渲染视频到界面基本流程

文章目录 OpenGL 简述特点和功能主要组件OpenGL ES当前状态 OpenGL ES 在 Android 上进行视频帧渲染总体流程 OpenGL 简述 OpenGL(Open Graphics Library)是一个跨平台的、语言无关的应用程序编程接口(API),用于开发生…

关于 Redis 中分布式锁

什么是分布式锁 在一个分布式系统中,也会涉及到多个节点访问同一个公共资源的情况。此时就需要通过锁来做互斥控制,避免出现类似于“线程安全”的问题。 而 Java 中的 synchronized 或者 C 中的 std::mutex,这样的锁都只能在当前进程中生效…

allure_pytest:AttributeError: ‘str‘ object has no attribute ‘iter_parents‘

踩坑记录 问题描述: 接口自动化测试时出现报错,报错文件是allure_pytest库 问题分析: 自动化测试框架是比较成熟的代码,报错也不是自己写的文件,而是第三方库,首先推测是allure_pytest和某些库有版本不兼…

Hadoop3:RPC通信原理及简单案例实现

一、场景介绍 我们知道,Hadoop中存在多种服务,那么,服务之间是如何通信的了? 比如,DN和NN之间如何通信? 这里,实际上是通过RPC实现进程间通信的了。 RPC属于Java网络编程范畴 需要编写客户端和…

Apache POI 使用Java处理Excel数据 进阶

1.POI入门教程链接 http://t.csdnimg.cn/Axn4Phttp://t.csdnimg.cn/Axn4P建议&#xff1a;从入门看起会更好理解POI对Excel数据的使用和处理 记得引入依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactI…

Java中锁的全面详解(深刻理解各种锁)

一.Monitor 1. Java对象头 以32位虚拟机位例 对于普通对象,其对象头的存储结构为 总长为64位,也就是8个字节, 存在两个部分 Kclass Word: 其实也就是表示我们这个对象属于什么类型,也就是哪个类的对象.而对于Mark Word.查看一下它的结构存储 64位虚拟机中 而对于数组对象,我…