跳到主要内容Java Web 开发:JSON 基础、@Test 测试与 Cookie/Session 处理 | 极客日志Javajava
Java Web 开发:JSON 基础、@Test 测试与 Cookie/Session 处理
综述由AI生成介绍 Java Web 开发中的 JSON 基础概念、JUnit @Test 注解用法以及 Cookie 和 Session 的机制。内容包括 JSON 语法规范、对象与数组结构、Java 对象与 JSON 字符串互转(使用 ObjectMapper)。此外,详细讲解了 @Test 测试方法的特点及其与 main 方法的区别。在 Web 交互部分,涵盖了 @RequestBody 接收 JSON、@PathVariable 获取 URL 参数、@RequestPart 文件上传、Cookie 与 Session 的存储获取流程及区别,最后介绍了如何获取 HTTP Header 信息。
Kubernet29 浏览 JSON 的概念
概念
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于 JavaScript 的一个子集,但采用了独立语言的文本格式,几乎所有编程语言都有支持 JSON 的库。
@Test 注解
什么是@Test?
@Test 是单元测试注解,用于标记'测试方法',让框架自动执行该方法以验证代码逻辑。
与 JSON 关联
- 测试 JSON 序列化/反序列化是否正常;
- 测试从 JSON 文件读取数据的功能是否正常。
public class JsonTest {
@Test
void test1(){
System.out.println(111);
}
@Test
void test2(){
System.out.println(222);
}
}
可以单个窗口执行,也可以多个窗口同时执行。
@Test 标记的方法与 main 方法的区别
| 对比 | @Test 标记的测试方法 | main 方法 |
|---|
| 作用 | 验证代码功能 | 程序入口,启动并指向核心业务逻辑 |
| 调用 | 由测试框架自动调用 | 由 JVM 自动调用(程序启动时) |
| 定义规范 | 必须是无参数 void | 必须是 public static void main(String[] args) |
| 独立性 | 每个测试方法应独立,不依赖执行顺序 | 代码逻辑顺序执行,依赖前后逻辑 |
| 场景 | 用于开发的测试验证 | 用于程序的实际运行 |
JSON 语法
核心数据类型
| 无序的键值对集合,用{}包裹;键必须是双引号包裹的字符串,值为任意 Json 类型 |
| 数组(Array) | 有序的值列表,用[]包裹;值可以是任意 Json 类型,且允许不同类型混合 |
| 字符串(String) | 必须双引号包裹(不能用单引号),支持转义字符 |
| 数字(Number) | 支持整数、浮点数、负数,不支持 NaN、Infinity;可省略小数点前/后数字 |
| 布尔值(Boolean) | 仅两个固定值:true 或 false |
| 空值(Null) | 仅一个固定值:null,表示'无数据' |
- JSON 的两个结构:JSON 的结构只能是对象或者数组,不能直接是字符串、数字等单个值;
- 键值必须是双引号,不能是单引号;
- 逗号分隔且无尾逗号:对象的键值对、数组的元素之间用逗号分隔,但是最后一个元素不能加逗号;
- JSON 不支持注释;
- 大小写敏感。
常见使用
对象
{ "name": "张三", "age": 30, "isStudent": false, "hobbies": ["篮球", "编程"], "address": { "city": "上海", "street": "XX 路" }, "score": null }
数组
[{ "id": 1, "name": "苹果", "price": 5.99 }, { "id": 2, "name": "香蕉", "price": 3.5 }, { "id": 3, "name": "橙子", "price": 4.2 }]
{"name":"张三","age":30,"isStudent":false,"hobbies":["篮球","编程"],"address":{"city":"上海","street":"XX 路"},"score":null}
[{"id":1,"name":"苹果","price":5.99},{"id":2,"name":"香蕉","price":3.5},{"id":3,"name":"橙子","price":4.2}]
JSON 字符串和 Java 对象的互转
public class UserInfo {
private String name;
private int age;
public UserInfo(){ }
public UserInfo(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override
public String toString() {
return "UserInfo{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
@Test
void test3() throws JsonProcessingException {
ObjectMapper objectMapper=new ObjectMapper();
UserInfo userInfo=new UserInfo("小熊",3);
String s=objectMapper.writeValueAsString(userInfo);
System.out.println(s);
}
throws JsonProcessingException:声明异常,因为 objectMapper.writeValueAsString() 可能抛出异常(序列化失败)
objectMapper:负责 JSON 的序列化(对象->JSON)和反序列化(JSON->对象),用于序列化操作
objectMapper.writeValueAsString():用于对象转 JSON 字符串。
@Test
void test4() throws JsonProcessingException {
ObjectMapper objectMapper=new ObjectMapper();
String s="{\"name\":\"小熊\",\"age\":3}";
UserInfo userInfo=objectMapper.readValue(s, UserInfo.class);
System.out.println(userInfo);
}
objectMapper.readValue():用于 JSON 转对象
UserInfo.class:表示要转换的目标类
- 简洁易读,语法简单直观;
- 跨语言兼容,几乎所有编程语言都支持;
- 轻量高效,传输和解析速度快;
- 与 JavaScript 无缝集成,适合 Web 开发;
- 结构化能力强,可灵活表示复杂数据,且易于扩展,安全性较高。
传递 JSON
接收 JSON 对象,需要用到 @RequestBody 注解。
@RequestBody:@RequestBody 就是'桥梁',把前端请求体里面的 JSON 数据,自动变成你能用的 JSON 对象,如果没有 @RequestBody,那么就无法接收到数据。
获取 URL 中的参数
获取 URL 中的参数,需要使用 @PathVariable 注解。
- 语法:{变量名}表示 url 的动态部分;
- 作用:在一个 url 下可以进行多种类似的请求
@RequestMapping("/11/{id}/{name}")
public String method10(@PathVariable("id") Integer id,@PathVariable("name") String name){
return "获取文章 id:"+id+" 获取文章 name:"+name;
}
@PathVariable("userid") 中的 userid 参数:指定要绑定的路径变量名称,可写可不写
@PathVariable("userid") 中指定的名称需要与 url 模版中的 {userid} 一致
上传文件:@RequestPart
@RequestPart:用于接收 multipart/form-data 类型请求中的文件或复杂对象的文件,常用于文件上传场景
@RequestMapping("/13")
public String method13(@RequestPart("file")MultipartFile file) throws IOException {
String filename= file.getOriginalFilename();
System.out.println(filename);
File file1=new File("D:/.temp/" + file.getOriginalFilename());
file.transferTo(file1);
return "文件上传成功";
}
- MultipartFile:文件上传处理接口;
- 使用
/ 是通用的路径分隔符,Windows 系统下通常用 \,但在 Java 字符串中需注意转义。
Cookie 和 Session
Cookie
什么是 Cookie?
Cookie 是 Web 服务器保存在用户浏览器上的小型文本文件。
- 首次访问网站,浏览器发送请求;
- 服务器生成 Cookie 信息,通过 Set-Cookie 响应头返回;
- 浏览器接收并保存 Cookie;
- 再次访问该网站时,浏览器自动在请求头中携带 Cookie;
- 服务器携带 Cookie,识别用户身份/状态,返回对应内容;
- Cookie 过期或被清除。
就好像,你第一次去超市买东西,办了一张卡,这张卡里面记录着你的积分和消费信息,随后放进钱包保存起来,你第二次去该超市买东西结账的时候,直接出示卡,就可以。收银员刷卡,就可以看到你的相关消费信息。会员卡到期了就无法使用或者失效。
Cookie 的获取
@RequestMapping("/14")
public String method14(HttpServletRequest request){
Cookie[] cookies=request.getCookies();
if(cookies!=null){
for (Cookie cookie:cookies) {
System.out.println(cookie.getName()+":"+cookie.getValue());
}
}
return "获取 Cookie 成功";
}
@RequestMapping("/15")
public String method15(@CookieValue("username") String name){
return "name"+name;
}
- HttpServletRequest:表示客户端发给服务器的 HTTP 请求。
- HttpServletResponse:表示服务器给客户端返回的 http 响应
Session
什么是 Session?
Session 是指计算网络中,客户端与服务器之间为完成特定交互(登录、购物)而建立的临时、有状态的连接或数据存储机制,核心作用是在无状态的 http 下,保护用户的身份信息和操作上下文。
- 创建 Session:用户首次访问服务器时,服务器会生成一个唯一的 SessionId,并在服务器端创建对应的 Session 数据存储;
- 传递 SessionId:服务器通过 Cookie 将 Session Id 发送给客户端,客户端会将其保存在本地;
- 后续交互验证:用户再次访问服务器时,客户端会自动携带 Cookie 中的 SessionId,服务器通过这个 SessionId 找到对应的 Session 数据,确认用户身份和上下文,提供个性化服务;
- 销毁 Session:当用户主动退出登录,Session 超时或服务器重新启动,数据就会被删除。
就好像,你(客户端)去一家酒店吃饭,让服务员点菜或者扫码点菜,就会生成一份属于自己的菜单(session 数据),服务员可以根据你的取餐码(sessionId),知道你点的有哪些东西。
Cookie 和 Session 之间的关系
| Cookie | Session |
|---|
| 存储位置 | 浏览器(客户端)存的'小纸条' | 服务器(服务端)存'用户档案' |
| 核心作用 | 传递 SessionId | 存用户会话'信息' |
| 依赖关系 | Session 通常靠 Cookie 传 ID 实现 | Cookie 常作为 Session 的'身份证' |
| 典型场景 | 记录登记状态(传 SessionId) | 存用户购物,登录信息 |
Session 的存储
@RequestMapping("/16")
public String method16(HttpServletRequest request){
HttpSession session=request.getSession();
session.setAttribute("name","lisi");
session.setAttribute("age","11");
return "存储 Session 成功";
}
Session 的获取
@RequestMapping("/17")
public String method17(HttpServletRequest request){
HttpSession session=request.getSession(false);
if(session==null){
return "用户未登录";
}else {
String username=(String) session.getAttribute("name");
String userage=(String) session.getAttribute("age");
return "用户名:"+username+" 年龄:"+userage;
}
}
@RequestMapping("/18")
public String method18(HttpSession session){
String username=(String) session.getAttribute("name");
String userage=(String) session.getAttribute("age");
return "用户名:"+username+" 年龄:"+userage;
}
@RequestMapping("/19")
public String method19(@SessionAttribute("name") String name,@SessionAttribute("age") String age){
return "用户名:"+name+" 年龄:"+age;
}
header(请求头/响应头):通信双方传递的'额外说明信息',就像点外卖上面的备注。
@RequestMapping("/20")
public String method20(HttpServletRequest request){
String agent=request.getHeader("User-Agent");
return "agent:"+agent;
}
@RequestMapping("/21")
public String method21(@RequestHeader("User-Agent") String agent){
return "agent:"+agent;
}
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online