文章目录
- 代码总结
- Cookie与Session
-
- Cookie
- Session
- Cookie与Session交互
- 常见面试题
-
- [Cookie 和 Session 的区别](#Cookie 和 Session 的区别)
- Session产生的SessionId放在Cookie里面,如果用户把Cookie禁止掉,是不是Session也不能用了呢?
- 获取Cookie与session
代码总结
初始化--@RestController、@RequestMapping
@RestController:该注解用于标记一个类作为RESTful Web 服务的控制器
@RequestMapping("/request"):该注解用于将 HTTP 请求映射到对应的控制器方法上,将特定的 URL 路径(如 "/request")映射到控制器类或方法。
url路径前加上"/"
建议类路径与方法路径一起使用
RequestMapping即支持get请求,也支持post请求,默认是get请求
java
@RequestMapping("/request")
@RestController//标记一个类作为RESTful Web 服务的控制器
public class RequestController {
//后面这个是url,建立客户端与服务器之间的连接
//可以修饰类,也可以修饰方法(修饰类时,访问路径: 类路径+访问路径)
@RequestMapping("/hello")
public String say(){
return "Hello Spring MVC";
}
}

传递参数
单参数
- 传递单参数时,需要保持方法的参数变量的名称与请求的名称一致。
- 使用基础类型与包装类型作为接收参数时,当请求为空时,包装类型只为null,基础类型会报出500错误,通常情况下只使用包装类型。
java
@RequestMapping("/r1")
public String r1(String name){
return "接收到参数: "+name;
}
@RequestMapping("/r2")
public String r2(Integer age){
return "接收到参数: "+age;
}
@RequestMapping("/r3")
public String r3(int age){
return "接收到参数: "+age;
}
多参数
当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果。
java
@RequestMapping("/r4")
public String r4(String name,Integer age){
return "接收到参数name="+name+" age="+age;
}
传递对象
- 如果参数⽐较多时,⽅法声明就需要有很多形参,并且后续每次新增⼀个参数,也需要修改⽅法声明,不妨把这些参数封装为⼀个对象。 Spring
- 根据参数名称⾃动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型在创建对象时赋值为默认初识值,⽐如int类型的属性,会被赋值为0,此时不会报错)
java
@RequestMapping("/r5")
public String r5(Student student){
return "接收到参数student: "+student;
}
后端参数重命名(后端参数映射)--@RequestParam
必传参数
@RequestParam:某些特殊的情况下,前端传递的参数key和后端接收的key可以不⼀致,⽐如前端传递了⼀个 name 给后端,而后端是使⽤ username 字段来接收,这样就会出现参数接收不到的情况,如果出现这种情况,使⽤ @RequestParam 来重命名前后端的参数值。
java
@RequestMapping("/r6")
public String r6(@RequestParam("name") String username){//接收前段的name赋值给后端的username
return "接收到参数student: "+username;
}
使⽤ @RequestParam 进⾏参数重命名时,请求参数只能和 @RequestParam 声明的名称一致,才能进⾏参数绑定和赋值。
使⽤ @RequestParam 进⾏参数重命名时,参数就变成了必传参数,也就是接收到为 null ,直接报错。
设置非必传参数
java
@RequestMapping("/r7")
public String r7(@RequestParam(value = "name",required = false) String username){
return "接收到参数student: "+username;
}
传递数组
Spring MVC可以⾃动绑定数组参数的赋值。
java
@RequestMapping("/r8")
public String r8(String[] arrays){
return "arrays: "+ Arrays.toString(arrays);
}
传递集合
集合参数:和数组类似,同⼀个请求参数名有为多个,且需要使⽤ @RequestParam 绑定参数关系。
这是因为后端不能直接接收集合这样的参数数组,所以先通过数组接收数据,再通过 @RequestParam 映射。
java
@RequestMapping("/r9")
public String r9(@RequestParam List<String> list){
return "arrays: "+ list;
}
传递JSON数据
JSON:JavaScriptObjectNotation 【JavaScript 对象表示法】
JSON是⼀种轻量级的数据交互格式,它基于ECMAScript(欧洲计算机协会制定的js规范)的⼀个⼦集,采⽤完全独⽴于编程语⾔的⽂本格式来存储和表示数据。
JSON是⼀种数据格式,有⾃⼰的格式和语法,使⽤⽂本表示⼀个对象或数组的信息,因此JSON本质是字符串。
JSON语法
数据在键值对(Key/Value) 中
数据由逗号 , 分隔
对象⽤ {} 表⽰
数组⽤ [] 表⽰
值可以为对象,也可以为数组,数组中可以包含多个对象
示例:
bash
{
"name":"zhangsan",
"id":1111,
"age":22
}
JSON格式转换
工具:https://www.bejson.com/,可以对JSON字符串进行压缩整理。
将上述JSON字符串进行压缩:
bash
{"name":"zhangsan","age":12,"id":1111}
JSON本质上是⼀个字符串,通过⽂本来存储和描述数据。
Spring MVC框架也集成了JSON的转换⼯具,可以直接使用,来完成JSON字符串和Java对象的互转。
java
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
String jsonstr = "{\"name\":\"zhangsan\",\"age\":12,\"id\":1111}";
//json字符串转对象,使用该方法时,类中必须要有无参数的构造函数
Student student = objectMapper.readValue(jsonstr,Student.class);
System.out.println(student);
//对象转json字符串
String s= objectMapper.writeValueAsString(student);
System.out.println(s);
}
JSON优点
- 简单易用:语法简单,易于理解和编写,可以快速地进⾏数据交换
- 跨平台⽀持:JSON可以被多种编程语⾔解析和生成,可以在不同的平台和语⾔之间进⾏数据交换和传输
- 轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占用宽带较小,可以提⾼数据传输速度
- 易于扩展:JSON的数据结构灵活,支持嵌套对象和数组等复杂的数据结构,便于扩展和使用
- 安全性:JSON数据格式是⼀种纯文本格式,不包含可执⾏代码,不会执⾏恶意代码,因此具有较⾼的安全性
传递JSON对象
接收JSON对象,需要使⽤ @RequestBody 注解。
RequestBody:请求正⽂,意思是这个注解作⽤在请求正⽂(body)的数据绑定,请求参数必须在写在请求正⽂中。
json格式字符串就在body(请求正文)中。
java
@RequestMapping("/r10")
public String r10(@RequestBody Student student) {
return "接收到参数student: " + student;
}
获取URL中参数--@PathVariable
@PathVariable:该注解主要作⽤在请求URL路径上的数据绑定,默认传递参数写在URL上,SpringMVC就可以获取到。
java
@RequestMapping("/article/{articleId}")
public String r11(@PathVariable("articleId") Integer articleId){//@PathVariable从url中获取参数
return "接收到参数articleId: " + articleId;
}
@RequestMapping("/article/{articleId}/{name}")
public String r12(@PathVariable("articleId") Integer articleId,@PathVariable("name") String name){
return "接收到参数articleId: " + articleId + " name: " + name;
}
传递文件--@RequestPart
@RequestPart("file") 也是起到类似于赋值的功能
java
@RequestMapping("/r13")
public String r13(@RequestPart("file") MultipartFile file) {//@RequestPart("file") 也是起到类似于赋值的功能
String originalFilename = file.getOriginalFilename();
return "接收文件,原始名称: " + originalFilename;
}
Cookie与Session
Cookie
Cookie,其实就是储存在用户本地终端上的数据(通常经过加密),由用户计算机暂时或永久保存的信息,类型为"小型文本文件"。
可以理解是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据。
Cookie机制
HTTP是无状态的,不能保存每次提交的信息,如果用户发来一个新请求,服务器无法知道它是否与上次的请求有联系。
cookie的出现就是为了解决这个问题
登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户再次发送请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户的状态。
此时在服务器这边就需要记录"令牌"信息,以及令牌对应的用户信息,这个就是 Session 机制所做的工作。
Session
Session--回话、对话:在计算机领域,会话是⼀个客户与服务器之间的不中断的请求响应,当客户明确结束会话或服务器在⼀个时限内没有接受到客⼾的任何请求时,会话就结束了。
服务器同⼀时刻收到的请求是很多的,服务器需要清楚的区分每个请求是从属于哪个客户,也就是属于哪个会话,就需要在服务器这边记录每个会话以及与客户的信息的对应关系。
Session是服务器是为了保存用户信息⽽创建的⼀个特殊的对象。Session的本质就是⼀个 "哈希表",存储了⼀些键值对结构,Key 就是SessionID,Value 就是⽤户信息(⽤户信息可以根据需求灵活设计)。
SessionId 是由服务器⽣成的⼀个 "唯⼀性字符串",从 Session 机制的⻆度来看,这个唯⼀性字符串称为 "SessionId",但是站在整个登录流程中看待,也可以把这个唯⼀性字符串称为 "token"。
Cookie与Session交互
- 当用户登录的时候,服务器在 Session 中新增⼀个新记录,并把 sessionId 返回给客⼾端(通过 HTTP 响应中的
Set-Cookie 字段返回) 。 - 客户端后续再给服务器发送请求的时候,需要在请求中带上 sessionId(通过 HTTP 请求中的 Cookie 字段带上)。
- 服务器收到请求之后,根据请求中的 sessionId在 Session 信息中获取到对应的用户信息,再进⾏后续操作,找不到则重新创建 Session ,并把SessionID返回。
- Session 默认是保存在内存中的,如果重启服务器则 Session 数据就会丢失。
- 同一客户端启动二次session_start的话,session_id是不一样的。
常见面试题
Cookie 和 Session 的区别
Cookie 是客户端保存用户信息的⼀种机制,Session 是服务器端保存用户信息的⼀种机制。
Cookie 和Session之间主要是通过 SessionId 关联起来的,SessionId 是 Cookie 和 Session 之间的桥梁。
Cookie 和 Session 经常会在⼀起配合使⽤,但是不是必须配合。
Session 中的 sessionId 也不需要非得通过 Cookie/Set-Cookie 传递,比如通过URL传递。
Session产生的SessionId放在Cookie里面,如果用户把Cookie禁止掉,是不是Session也不能用了呢?
禁止掉cookie后,session当然可以用,不过通过其他的方式来获得这个sessionid,比如,可以跟在url的后面,或者以表单的形势提交到服务器端,从而使服务器端了解客户端的状态。
获取Cookie与session
获取Cookie
传统获取Cookie
Spring MVC是基于 Servlet API 构建的原始 Web 框架,也是在Servlet的基础上实现的。HttpServletRequest , HttpServletResponse 是Servlet提供的两个类,是 Spring MVC 的内置对象,要时直接在⽅法中添加声明即可。
HttpServletRequest 对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的⽅法,可以获得客户端请求的所有信息。
HttpServletResponse 对象代表服务器的响应,HTTP响应的信息都在这个对象中,⽐如向客户端发送的数据,响应头、状态码等,通过这个对象提供的⽅法,可以获得服务器响应的所有内容。
该方法通过遍历 request 中所有 Cookie 得到一个 cookies数组。
java
@RequestMapping("getC")
public String getCookie(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
Arrays.stream(cookies).forEach(cookie -> {
System.out.println(cookie.getName() + " : " + cookie.getValue());
});
}
return "获取Cookie";
}
此时没有设置Cookie,通过浏览器访问:http://127.0.0.1:8080/getC ,得到Cookie为null
通过PostMan可以设置⼀下Cookie的值,进而进行测试。
简洁获取Cookie
@CookieValue("Cookie_1")只能获取Cookie数组中某个指定cookie,这里指定的是刚才通过PostMan创建的Cookie。
java
@RequestMapping("/getC2")
public String getCookie2(@CookieValue("Cookie_1") String cookie) {
return "从Cookie中获取值,cookie"+cookie;
}
获取Session
设置Session
Session是服务器端的机制,需要先存储,才能再获取。
该方法创建了一个Session----SessionId : {name:zhangsan}。
java
@RequestMapping("/setSess")
public String setSession(HttpServletRequest request) {
//从Cookie中获取到了sessionID,根据senssionID获取session对象,如果没有获取到,会创建一个session对象
HttpSession session = request.getSession();
session.setAttribute("name","zhangsan");
return "设置session成功";
}
传统获取Session
Object getAttribute(String name):返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回null。
该方法返回服务器端name的信息。
java
@RequestMapping("/getSess")
public String getSession(HttpServletRequest request) {
//从Cookie中获取到了sessionID,根据senssionID获取session对象
HttpSession session = request.getSession();
String name = (String)session.getAttribute("name");
return "从session中获取name: "+name;
}
简洁获取Session
java
@RequestMapping("getSess2")
public String getSession(HttpSession session) {
String name = (String) session.getAttribute("name");
return "name:" + name;
}