《JavaEE进阶》----5.<SpringMVC②剩余基本操作(CookieSessionHeader响应)>

Cookie和Session简介。
Spring MVC的

2.请求
Cookie的设置和两种获取方式
Session的设置和三种获取方式。

3.响应

1.返回静态页面

2.返回数据

3.返回HTML片段

4.返回JSON

5.设置状态码

6.设置header

三、(接上文)SpringMVC剩余基本操作

3.2postman请求

3.2.10 获取Cookie和Session

1.理解Cookie

我们知道HTTP协议自身是“无状态”协议。

"无状态" 的含义指的是:

默认情况下 HTTP 协议的客⼾端和服务器之间的这次通信和下次通信之间没有直接的联系.

实际开发中,我们很多时候需要知道请求之间的关联关系。

例如登陆网站成功后,第二次访问的时候服务器就能知道该请求是否是已经登陆过了.

当用户输入用户名和密码点击登录后,服务器响应,这时候登陆成功后,服务器会给用户一个“令牌”,这样下次用户再访问,就会带上“令牌”。服务器就知道这个用户已经登陆过了。

"令牌" 通常就存储在 Cookie 字段中.

此时在服务器这边就需要记录"令牌"信息,以及令牌对应的用户信息,这个就是 Session 机制所做的工作.

2.理解Session

此时在服务器这边就需要记录"令牌"信息,以及令牌对应的用户信息,这个就是 Session 机制所做的工作.

Session就是会话的意思,比如10个浏览器请求同一个服务器(同样的进程)。那么就会产生10个会话。这10个会话,服务器会通过Session来分辨出会话是哪个浏览器请求的。

服务器同⼀时刻收到的请求是很多的.服务器需要清楚的区分每个请求是从属于哪个用户,也就是属于哪个会话,就需要在服务器这边记录每个会话以及与用户的信息的对应关系. Session是服务器为了保存用户信息而创建的⼀个特殊的对象.

 Session的本质就是⼀个 "哈希表",存储了⼀些键值对结构.Key就是SessionID,Value就是用户信息(用户信息可以根据需求灵活设计)。

SessionID就是由服务器生成的,“唯一性”字符。从Session机制角度看来,这个唯一性字符就是SessionID。如果站在登录流程中看待,也可以把这个唯一性字符称作“token”。

3.Cookie 和 Session之间的关系。(举例)


举一个生活中的例子,新生入学,学校会收录学生信息存储在教务系统,并为每一个学生设定学号

存储学生信息示例如下:

001        张三        18        计科1班

002        李四        19        计科1班

003        王五        18        计科1班

这里的信息就相当于Session


而学校存储信息之后,会给学生发学生证。

出入校园,使用学生证来证明学生身份。

这里的学生证就相当于Cookie

注意:

学生证(Cookie):是可以造假。

教务系统信息(Session):一定是真的

4.Cookie和session的区别

5.获取Cookie (两种方式)

①传统写法(可获取所有Cookie)
@RestController
@RequestMapping("/request")
public class RequestController {/*** 传统方法获取Cookie* 每个方法都内置了HttpServletRequest request/HttpServletResponse response对象* @param request* @param response* @return*/@RequestMapping("/getCookie")public String getCookie(HttpServletRequest request, HttpServletResponse response){Cookie[] cookies = request.getCookies();//通过这种方式可以获取Cookie//我们使用lambda表达式的方式来打印Cookie。这种写法可以先了解一下。
//        Arrays.stream(cookies).forEach(x->{
//            System.out.println(x.getName() + ":" + x.getValue());
//        });//等价于使用foreach循环来打印Cookiefor (Cookie c: cookies){System.out.println(c.getName()+":"+c.getValue());}return "获取Cookie成功!!!";}
}

 

注意,如果Cookie为空,会报异常。因此写法如下。 

    @RequestMapping("/getCookie")public String getCookie(HttpServletRequest request, HttpServletResponse response){Cookie[] cookies = request.getCookies();//通过这种方式可以获取Cookie
//使用foreach循环来打印Cookieif(cookies != null){for (Cookie c: cookies){System.out.println(c.getName()+":"+c.getValue());}return "获取Cookie成功!!!";}return "Cookie为空!";}

运行结果 

当我们添加Cookie之后,刷新一下

 

Cookie也被打印在控制台上。从这里也可以看出,Cookie是可以造假,除了通过浏览器造假,通过Postman也是可以造假的。 

②Spring Boot写法(@CookieValue注解获取指定Cookie)

我们使用postman添加几个Cookie,当我们使用传统方式打印Cookie

 

我们得到了所有的Cookie。但是当我们用SpringBoot方式打印。我们只能通过注解 

@CookieValue来或者指定key值的cookie。

    @RequestMapping("getCookie2")public String getCookie2(@CookieValue("yang")String yang){return "yang:"+yang;}

 

 因此使用这两种方法取决于你想要获取

全部Cookie还是

只获得某些Cookie

6.获取Session

①传统写法
    @RequestMapping("setSession")public String setSession(HttpServletRequest request){HttpSession session = request.getSession();session.setAttribute("student","zzx");return "设置Session成功!";}@RequestMapping("getSession")public String getSession(HttpServletRequest request){HttpSession session = request.getSession();
//默认值为ture,如果Session为null,就创建一个空的SessionString student = (String) session.getAttribute("student");return "登录用户:"+student;}

 http://127.0.0.1:1208/request/setSession

http://127.0.0.1:1208/request/getSession

②SpringBoot写法()
I.直接使用内置对象HttpSession session获取Session。
    @RequestMapping("getSession2")public String getSession(HttpSession session){String student = (String) session.getAttribute("student");return "登录用户:"+student;}

II.使用注解 (@SessionAttribute)
    @RequestMapping("getSession3")public String getSession(@SessionAttribute("student")String student){return "登录用户:"+student;}

虽然这样写如下代码非常的简短,但是也有一个问题就是如果直接getSession。会报错 

 

没有找到student这个类型。这是因为加了注解之后,这个参数就变成了必传参数,因此不能为空。

如何修改呢,如下: @SessionAttribute(value = "student",required = false)

    @RequestMapping("getSession3")public String getSession(@SessionAttribute(value = "student",required = false)String student){return "登录用户:"+student;}

 

此时就不报错了。 

3.2.11 获取Header

我们请求打印Header。中的 User-Agent 的信息。

它表示用的哪个客户端去请求的。

①传统方式

    @RequestMapping("/getHeader")public String getHeader(HttpServletRequest request){String userAgent = request.getHeader("User-Agent");return "userAgent:"+userAgent;}

②SpringBoot方式(@RequestHeader注解) 

    @RequestMapping("/getHeader2")public String getHeader2(@RequestHeader("User-Agent")String userAgent){return "userAgent:"+userAgent;}

 

上图:当我们使用Postman请求。 

 

上图:当我们使用浏览器请求。  

我们只想获取Header信息中的其中的一个,使用SpringBoot方式很方便。

当我们想要获取多个内容,使用SpringBoot方式就需要写很多参数。

因此我们可以使用传统方式更加方便的获取。

 请求完结。

3. 3响应:

在响应中,我们有以下操作:

1.返回静态页面

2.返回数据

3.返回HTML片段

4.返回JSON

5.设置响应头(状态码,编码或者其他header)

我们可以

使用Fiddler来查看请求和响应的数据

执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤⼾,也就是响应.

1.返回静态页面(页面)

首先要有一个静态页面,

创建前端页面index.html(注意路径)。

如果要访问的目录在静态目录static下面,还有其他目录,那么路径url中需要带上这个目录

@Controller
@RequestMapping("/return")
public class ReturnController {@RequestMapping("/r1")public String r1(){return "/index.html";}
}

 

 注意: 

1.在SpringBoot中。@RequestMapping中的/是可以被省略的。而return中的/不能省略。

2.当我们想要访问静态页面时,我们需要把原先

@RestController注解改为@Controller

@RestController注解与@Controller的区别和联系

想要返回数据使用:@RestController

想要返回页面使用:@Controller

@RestController = @ResponseBody + @Controller

@Controller:告诉Spring帮我们管理哪些程序,默认返回的是页面

@ResponseBody:表示返回数据

 我们看看注解@RestController的源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {@AliasFor(annotation = Controller.class)String value() default "";
}

注解解释 

@Target:表示注解的使用范围如上:ElementType.TYPE 表示注解只能修饰类

@Retention:表示注解的生命周期

我们看看注解@Controller的源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {@AliasFor(annotation = Component.class)String value() default "";
}

2.返回数据 @ResponseBody注解

源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}

表示返回数据。响应正文里面的内容。

这里区别@RequestBody:是请求正文里面的内容。接收JSON的时候我们经常用到。

它既可以修饰类,也可以修饰方法。

修饰类:表示该类所有的方法,返回的都是数据

修饰方法:表示该方法的返回都是数据。

示例:

    @ResponseBody@RequestMapping("/r2")public String r2(){return "hello ,SpringMVC,我是返回的数据";}


 

ps:关于路径中是否有项目名&一个项目部署多个服务/部署多个项目

 

 

3.返回HTML片段(数据)

    @ResponseBody@RequestMapping("/r3")public String r3(){return "<h1>hello ,SpringMVC,我是HTML片段</h1>";}

 

 

注意这里文本类型是html。

content-Type:text/html

无论返回的是页面,还是数据。content-Type类型都是html

如果让它返回JSON呢?请往下看。

ps:get和post的区别

get可以被缓存,get是幂等的。不管什么时候请求,得到响应是一样的。

post不可以被缓存。

4.返回JSON(对象,哈希表等键值对格式)

JSON通常也是表示对象,我们返回一个对象试试。

    @ResponseBody@RequestMapping("/r4")public UserInfo r4(){UserInfo userInfo = new UserInfo();userInfo.setName("zzx");userInfo.setId(9);userInfo.setAge(18);return userInfo;}

 

 

如上如,我们返回对象成功返回了JSON类型的文本。 

content-Type:application/json 

    @ResponseBody@RequestMapping("/r5")public Map<String,String> r5(){HashMap map = new HashMap<>();map.put("k1","v1");map.put("k2","v3");map.put("k3","v3");return map;}

 

content-Type:application/json 

如上如,使用Map也成功返回了JSON类型的文本。 

    @RequestMapping("/r6")public String r6(){return "/a.js";}

 

 content-Type:application/javascript

成功返回了页面a.js

    @RequestMapping("/r7")public String r7(){return "/b.css";}

 

 content-Type:text/css

成功返回了页面b.css

总结:

在SpringBoot中, content-Type  不需要我们自己设置。

会自动根据我们的返回的结果自行设置。

5.设置状态码(HttpServletResponse)

状态码的设置不影响页面的展示。

错误显示可以自定义的图。也有很多公共的页面格式。

    @ResponseBody@RequestMapping("/r8")public String r8(HttpServletResponse response){response.setStatus(401);return "设置状态成功!";}

 

6.设置Header(了解)

Http响应报头也会向客户端传递⼀些附加信息,

比如服务程序的名称,请求的资源已移动到新地址等

如:Content-Type、Local等.

这些信息通过@RequestMapping注解的属性来实现

先来看@RequestMapping的源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {String name() default "";@AliasFor("path")String[] value() default {};@AliasFor("value")String[] path() default {};RequestMethod[] method() default {};String[] params() default {};String[] headers() default {};String[] consumes() default {};String[] produces() default {};
}

简单了解一下它的属性:(了解就好,不用记)

1.value:指定映射的URL

下面这些属性更多的是对请求的限制

2.method:指定请求的method类型,如GET,POST等

3.consumes:指定处理请求(request)的提交内容类型(Content-Type),例如application/json、text/html;

4.produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回

5.Params:指定request中必须包含某些参数值时,才让该方法处理

6.headers:指定request中必须包含某些指定的header值,才能让该方法处理请求

我们前面了解到,在Spring中,content-Type:的类型不需要我们自己设置,不过在工作中可能有时候还需要我们设置。

而且有些 Header 是自定义的。

什么都没写的时候,我们发现只有

这样的如

Content-Type:

Content-Length:

Data:

Keep-Alive:

Connection:

但是我们访问其他网站,就会发现会有许多。有些就是他们自定义的。

设置Content-Type(produce属性):

SpringBoot给我们默认的是 text/html 类型。要想我们自定义,我们就要用到

@RequestMapping的produce属性。下面是我们给它设置成json的代码:

    @ResponseBody@RequestMapping(value = "/r9",produces = "application/json")public String r9(){return "自定义Header中的Content-Type成功!";}

那么我们返回的本身就不是json,如果不自定义,那么就是text/html

什么时候会使用这种情况呢?

比如当我们返回{"ok":1}这串数据,是json格式,但是Spring这里默认还是html。这样就可以会对前端造成一定的影响。不过现在前端框架也更新了,可以自动识别为json

通过这样我们也可以在后面写

@RequestMapping(value = "/r9",produces = "application/json;charset = utf-8")

因此也可以同步的设置编码。

自定义Header(HttpServletResponse) 
    @ResponseBody@RequestMapping(value = "/r10")public String r10(HttpServletResponse response){response.setHeader("myHeader","myHeaderValue");return "自定义Header成功!";}

这就多了一个

myHeader:myHeaderValue


对于SpringMVC来说,掌握了以上3个功能(建立链接+请求+响应)就相当于掌握了SpringMVC. 

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

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

相关文章

两大电商巨头强强联手,实力宠卖家,一键通9国市场!

独家深度剖析&#xff0c;Lazada与Daraz分别作为东南亚与南亚电商领域的璀璨明星&#xff0c;正携手演绎一场前所未有的商业盛宴。这两大电商巨擘的强强联合&#xff0c;不仅标志着电商版图的一次重大扩张&#xff0c;更是为全球商家开启了一扇通往东南亚与南亚九大市场广阔蓝海…

Uniapp 调用aar、jar包

废话 坑是真的多&#xff0c;官方文档简陋到可以忽略不计。 大概流程 1. 新建一个Android模块&#xff0c;需要用这个模块打包成aar 2. 用这个模块引用uniapp-v8-release.aar以及你需要用到的aar、jar&#xff0c;用不到则忽略这步 坑一&#xff1a;不要直接放到这个模块的…

详解JavaScript

目录 JavaScript 引入样式 基础语法 变量 数据类型 运算符 JavaScript对象 数组 数组定义 数组操作 函数 语法格式 关于参数个数 函数表达式 对象 JQuery 语法 选择器 事件 常见的事件 操作元素 获取/设置元素内容 获取/设置元素属性 获取/设置CSS属性 …

StringTable

10.1. String的基本特性 String&#xff1a;字符串&#xff0c;使用一对""引起来表示String声明为final的&#xff0c;不可被继承String实现了Serializable接口&#xff1a;表示字符串是支持序列化的。String实现了Comparable接口&#xff1a;表示string可以比较大小…

JMeter 工具安装以及简单使用

一、安装以及汉化 傻瓜式JMeter下载和环境配置及永久汉化-CSDN博客https://blog.csdn.net/weixin_45608163/article/details/136528719 二、发送GET请求 配置请求头: 配置该线程组的请求: 放在线程组统计,下面请求则共享配置

[图解]SysML和EA建模住宅安全系统-活动作为块

1 00:00:00,210 --> 00:00:04,360 下一个步骤是识别潜在的失效 2 00:00:06,850 --> 00:00:11,150 这里它是用一个块定义图来表达的 3 00:00:12,150 --> 00:00:16,790 图17.21&#xff0c;失效模式识别和因果依赖 4 00:00:19,110 --> 00:00:22,400 但是这个块定义…

Java基于微信小程序的美食推荐小程序,附源码

博主介绍&#xff1a;✌Java徐师兄、7年大厂程序员经历。全网粉丝13w、csdn博客专家、掘金/华为云等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不…

通过Docker部署Nacos,以及Docker Desktop进行管理

目录 一.不需要持久化存储 1.启动容器 2.查看容器和镜像​ 3.容器管理 二.持久化存储启动mysql容器 1.创建docker卷 2.运行容器,指定卷 3.在nacos里面随便建个配置文件 4.停止并删除nacos容器 5.重新运行容器,并且挂载相同的卷,也就是上面第二步的命令 6.打开nacos并…

fiddler安装和汉化和抓https的包

下载和汉化 官网下载 https://www.telerik.com/ 1、「安装英文版Fiddler」、假如将Fiddler安装在&#xff1a;「D:\Programs\Fiddler」 2、将压缩包「fiddler菜单汉化」文件夹中的「FiddlerTexts.txt」复制到「D:\Programs\Fiddler\」 3、将压缩包「fiddler菜单汉化」文件夹…

外部排序之文件归并

概述 外部排序&#xff08;External Sorting&#xff09;是一种用于处理无法完全加载到内存中的大量数据的排序技术。由于内存的限制&#xff0c;传统的内存排序算法&#xff08;如快速排序、归并排序&#xff09;可能无法处理超大规模的数据集合。因此&#xff0c;需要采用外…

JVM面试(一)什么是虚拟机?什么是class文件?

什么是java虚拟机&#xff1f; 如果通俗点来讲&#xff0c;我们在电脑上一行行敲出来的代码&#xff0c;电脑本身是不认识的&#xff0c;最终是要转成电脑可以运行的101001这种字节。 但是这些我们又不可能手动来转换&#xff0c;所以呢&#xff0c;就需要一个工具&#xff0…

PyCharm中python语法要求——消去提示波浪线

PyCharm中python语法要求——消去提示波浪线 关闭代码规范检查 在Setting里边搜索pep&#xff0c;取消勾选pep8 coding style violation 问题产生 解决问题 按照下图操作&#xff0c;也可直接CtrlAlts弹出设置页面 在 Settings 中 &#xff1a; Editor > Color Sheame >…

Nginx: TCP建立连接的优化和启用Fast Open功能

TCP 建立连接优化 在三次握手中&#xff0c;相关TCP的内核参数可优化这一过程 net.ipv4.tcp_syn_retries 6net.ipv4.tcp_synack_retries 5net.ipv4.tcp_syncookies 0net.ipv4.tcp_max_syn_backlognet.core.somaxconnnet.core.netdev_max_backlog 1 &#xff09; net.ipv4…

书生大模型实战营(1)——InterStudio基础知识+Vscode SSH连接远程服务器+Linux基础指令

参加书生.浦江大模型实战训练营&#xff0c;学习大模型知识和微调技术&#xff0c;所有课程免费&#xff0c;通过闯关的形式学习&#xff0c;也比较有趣。一起来了解LLM的世界。邀请链接 产品简介 InternStudio 是大模型时代下的云端算力平台。基于 InternLM 组织下的诸多算法…

【工控】线扫相机小结 第二篇

背景 上一篇中《线扫相机小结》中介绍了一些基础知识和注意事项&#xff0c;这一篇是对上一篇的进一步补充。 会介绍线扫相机的一些调试技巧。 如何在线调试&#xff1f; 我们知道&#xff0c;线扫相机不能像面阵相机一样实时的呈现图像&#xff0c;只能一行行的扫描&#x…

HX711—称重模块

1、简介 HX711 采用了海芯科技集成电路专利技术&#xff0c; 是一款专为高精度电子秤而设计的 24 位 A/D 转 换器芯片。 2、原理图 PCB参考设计原理图 3、模块驱动代码&#xff08;固件库&#xff09; 数据读取代码分析 HX711信号读取时序 初始化&#xff1a; 将 PD_SCK&…

原生冻结进程分析(U)

一、概要 1.定义&#xff1a; 当应用切换到后台并且没有其他活动时&#xff0c;系统会在一定时间内通过状态判断&#xff0c;将进程 ID 迁移到冻结的 cgroup 节点上&#xff0c;实现冻结 CACHE 应用。这项功能可以减少活跃缓存应用在后台存在时所消耗的 CPU 资源&#xff0c;从…

armv8 memory model概述

概述 在armv8 架构中&#xff0c;它引入了更多的维度来描述内存模型&#xff0c;从而在此基础上进行硬件优化(但其中一些并未被主流的软件所接受)&#xff0c;在此做一些简单的整理&#xff0c;更多信息请参考 Arm spec 以及 AMBA 协议。下文主要是对Memory 和 Device 两大类的…

基于nodejs+vue+uniapp的摄影竞赛小程序

开发语言&#xff1a;Nodejs框架&#xff1a;expressuniapp数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;VS Code 系统展示 管理员登录 管理员主界面 用户管理 书籍分类管理 书籍信息管理 系统管理…

昇腾AI处理器的计算核心 - AI Core即DaVinci Core

昇腾AI处理器的计算核心 - AI Core即DaVinci Core flyfish 从一段代码的解释开始 template <typename T> class GlobalTensor { public:void setGlobalBuffer(T* buffer, uint32_t buffersize) {// 在这里实现设置全局缓冲区的逻辑} };语法的说明&#xff0c;主要用于…